mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
gst/librfb/: Add Hextile encoding
Original commit message from CVS: * gst/librfb/gstrfbsrc.c: * gst/librfb/rfbdecoder.c: * gst/librfb/rfbdecoder.h: Add Hextile encoding
This commit is contained in:
parent
cf69768bfb
commit
798aca639b
4 changed files with 201 additions and 142 deletions
|
@ -1,3 +1,10 @@
|
|||
2008-11-05 Thijs Vermeir <thijsvermeir@gmail.com>
|
||||
|
||||
* gst/librfb/gstrfbsrc.c:
|
||||
* gst/librfb/rfbdecoder.c:
|
||||
* gst/librfb/rfbdecoder.h:
|
||||
Add Hextile encoding
|
||||
|
||||
2008-11-05 Zaheer Abbas Merali <zaheerabbas at merali dot org>
|
||||
|
||||
patch by: Josep Torra
|
||||
|
|
|
@ -49,6 +49,7 @@ enum
|
|||
};
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (rfbsrc_debug);
|
||||
GST_DEBUG_CATEGORY (rfbdecoder_debug);
|
||||
#define GST_CAT_DEFAULT rfbsrc_debug
|
||||
|
||||
static const GstElementDetails gst_rfb_src_details =
|
||||
|
@ -88,11 +89,7 @@ static gboolean gst_rfb_src_event (GstBaseSrc * bsrc, GstEvent * event);
|
|||
static GstFlowReturn gst_rfb_src_create (GstPushSrc * psrc,
|
||||
GstBuffer ** outbuf);
|
||||
|
||||
#define DEBUG_INIT(bla) \
|
||||
GST_DEBUG_CATEGORY_INIT (rfbsrc_debug, "rfbsrc", 0, "rfb src element");
|
||||
|
||||
GST_BOILERPLATE_FULL (GstRfbSrc, gst_rfb_src, GstPushSrc, GST_TYPE_PUSH_SRC,
|
||||
DEBUG_INIT);
|
||||
GST_BOILERPLATE (GstRfbSrc, gst_rfb_src, GstPushSrc, GST_TYPE_PUSH_SRC);
|
||||
|
||||
static void
|
||||
gst_rfb_src_base_init (gpointer g_class)
|
||||
|
@ -112,6 +109,9 @@ gst_rfb_src_class_init (GstRfbSrcClass * klass)
|
|||
GstBaseSrcClass *gstbasesrc_class;
|
||||
GstPushSrcClass *gstpushsrc_class;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (rfbsrc_debug, "rfbsrc", 0, "rfb src element");
|
||||
GST_DEBUG_CATEGORY_INIT (rfbdecoder_debug, "rfbdecoder", 0, "rfb decoder");
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstbasesrc_class = (GstBaseSrcClass *) klass;
|
||||
gstpushsrc_class = (GstPushSrcClass *) klass;
|
||||
|
@ -231,18 +231,7 @@ gst_rfb_property_set_version (GstRfbSrc * src, gchar * value)
|
|||
static gchar *
|
||||
gst_rfb_property_get_version (GstRfbSrc * src)
|
||||
{
|
||||
gchar *version = g_malloc (8);
|
||||
gchar *major = g_strdup_printf ("%d", src->version_major);
|
||||
gchar *minor = g_strdup_printf ("%d", src->version_minor);
|
||||
|
||||
g_stpcpy (version, major);
|
||||
g_strlcat (version, ".", 8);
|
||||
g_strlcat (version, minor, 8);
|
||||
|
||||
g_free (major);
|
||||
g_free (minor);
|
||||
|
||||
return version;
|
||||
return g_strdup_printf ("%d.%d", src->version_major, src->version_minor);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -355,7 +344,7 @@ gst_rfb_src_start (GstBaseSrc * bsrc)
|
|||
GST_DEBUG_OBJECT (src, "connecting to host %s on port %d",
|
||||
src->host, src->port);
|
||||
if (!rfb_decoder_connect_tcp (decoder, src->host, src->port)) {
|
||||
GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
|
||||
("Could not connect to host %s on port %d", src->host, src->port));
|
||||
rfb_decoder_free (decoder);
|
||||
return FALSE;
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#define RFB_SET_UINT16(ptr, val) (*(guint16 *)(ptr) = GUINT16_TO_BE (val))
|
||||
#define RFB_SET_UINT8(ptr, val) (*(guint8 *)(ptr) = val)
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (rfbdecoder_debug);
|
||||
GST_DEBUG_CATEGORY_EXTERN (rfbdecoder_debug);
|
||||
#define GST_CAT_DEFAULT rfbdecoder_debug
|
||||
|
||||
#if 0
|
||||
|
@ -56,18 +56,13 @@ static void rfb_decoder_rre_encoding (RfbDecoder * decoder, gint start_x,
|
|||
gint start_y, gint rect_w, gint rect_h);
|
||||
static void rfb_decoder_corre_encoding (RfbDecoder * decoder, gint start_x,
|
||||
gint start_y, gint rect_w, gint rect_h);
|
||||
static void rfb_decoder_hextile_encoding (RfbDecoder * decoder, gint start_x,
|
||||
gint start_y, gint rect_w, gint rect_h);
|
||||
|
||||
RfbDecoder *
|
||||
rfb_decoder_new (void)
|
||||
{
|
||||
RfbDecoder *decoder = g_new0 (RfbDecoder, 1);
|
||||
static gboolean debug_inited = FALSE;
|
||||
|
||||
if (!debug_inited) {
|
||||
/* FIXME this is the wrong place to int this */
|
||||
GST_DEBUG_CATEGORY_INIT (rfbdecoder_debug, "rfbdecoder", 0, "Rfb source");
|
||||
debug_inited = TRUE;
|
||||
}
|
||||
|
||||
decoder->fd = -1;
|
||||
|
||||
|
@ -80,6 +75,8 @@ rfb_decoder_new (void)
|
|||
decoder->rect_width = 0;
|
||||
decoder->rect_height = 0;
|
||||
decoder->shared_flag = TRUE;
|
||||
decoder->data = NULL;
|
||||
decoder->data_len = 0;
|
||||
|
||||
return decoder;
|
||||
}
|
||||
|
@ -91,6 +88,9 @@ rfb_decoder_free (RfbDecoder * decoder)
|
|||
|
||||
if (decoder->fd >= 0)
|
||||
close (decoder->fd);
|
||||
|
||||
if (decoder->data)
|
||||
g_free (decoder->data);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@ -152,23 +152,26 @@ rfb_decoder_read (RfbDecoder * decoder, guint32 len)
|
|||
{
|
||||
guint32 total = 0;
|
||||
guint32 now = 0;
|
||||
guint8 *address = NULL;
|
||||
|
||||
g_return_val_if_fail (decoder->fd > 0, NULL);
|
||||
g_return_val_if_fail (len > 0, NULL);
|
||||
|
||||
address = g_malloc (len);
|
||||
g_return_val_if_fail (address, NULL);
|
||||
if (G_UNLIKELY (len > decoder->data_len)) {
|
||||
if (decoder->data)
|
||||
g_free (decoder->data);
|
||||
decoder->data = g_malloc (len);
|
||||
decoder->data_len = len;
|
||||
}
|
||||
|
||||
while (total < len) {
|
||||
now = recv (decoder->fd, address + total, len - total, 0);
|
||||
now = recv (decoder->fd, decoder->data + total, len - total, 0);
|
||||
if (now <= 0) {
|
||||
GST_WARNING ("rfb read error on socket");
|
||||
return NULL;
|
||||
}
|
||||
total += now;
|
||||
}
|
||||
return address;
|
||||
return decoder->data;
|
||||
}
|
||||
|
||||
static gint
|
||||
|
@ -251,18 +254,16 @@ rfb_decoder_send_pointer_event (RfbDecoder * decoder,
|
|||
static gboolean
|
||||
rfb_decoder_state_wait_for_protocol_version (RfbDecoder * decoder)
|
||||
{
|
||||
guint8 *buffer = NULL;
|
||||
rfb_decoder_read (decoder, 12);
|
||||
|
||||
buffer = rfb_decoder_read (decoder, 12);
|
||||
g_return_val_if_fail (memcmp (decoder->data, "RFB 003.00", 10) == 0, FALSE);
|
||||
g_return_val_if_fail (*(decoder->data + 11) == 0x0a, FALSE);
|
||||
|
||||
g_return_val_if_fail (memcmp (buffer, "RFB 003.00", 10) == 0, FALSE);
|
||||
g_return_val_if_fail (*(buffer + 11) == 0x0a, FALSE);
|
||||
|
||||
GST_DEBUG ("\"%.11s\"", buffer);
|
||||
*(buffer + 7) = 0x00;
|
||||
*(buffer + 11) = 0x00;
|
||||
decoder->protocol_major = atoi ((char *) (buffer + 4));
|
||||
decoder->protocol_minor = atoi ((char *) (buffer + 8));
|
||||
GST_DEBUG ("\"%.11s\"", decoder->data);
|
||||
*(decoder->data) = 0x00;
|
||||
*(decoder->data + 11) = 0x00;
|
||||
decoder->protocol_major = atoi ((char *) (decoder->data + 4));
|
||||
decoder->protocol_minor = atoi ((char *) (decoder->data + 8));
|
||||
GST_DEBUG ("Major version : %d", decoder->protocol_major);
|
||||
GST_DEBUG ("Minor version : %d", decoder->protocol_minor);
|
||||
|
||||
|
@ -283,7 +284,6 @@ rfb_decoder_state_wait_for_protocol_version (RfbDecoder * decoder)
|
|||
rfb_decoder_send (decoder, (guint8 *) "RFB 003.003\n", 12);
|
||||
|
||||
decoder->state = rfb_decoder_state_wait_for_security;
|
||||
g_free (buffer);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -295,17 +295,12 @@ static gboolean
|
|||
rfb_decoder_state_reason (RfbDecoder * decoder)
|
||||
{
|
||||
gint reason_length;
|
||||
guint8 *buffer = NULL;
|
||||
|
||||
buffer = rfb_decoder_read (decoder, 4);
|
||||
rfb_decoder_read (decoder, 4);
|
||||
|
||||
reason_length = RFB_GET_UINT32 (buffer);
|
||||
g_free (buffer);
|
||||
buffer = NULL;
|
||||
buffer = rfb_decoder_read (decoder, reason_length);
|
||||
GST_WARNING ("Reason by server: %s", buffer);
|
||||
|
||||
g_free (buffer);
|
||||
reason_length = RFB_GET_UINT32 (decoder->data);
|
||||
rfb_decoder_read (decoder, reason_length);
|
||||
GST_WARNING ("Reason by server: %s", decoder->data);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -313,8 +308,6 @@ rfb_decoder_state_reason (RfbDecoder * decoder)
|
|||
static gboolean
|
||||
rfb_decoder_state_wait_for_security (RfbDecoder * decoder)
|
||||
{
|
||||
guint8 *buffer = NULL;
|
||||
|
||||
/*
|
||||
* Version 3.3 The server decides the security type and sends a single word
|
||||
*
|
||||
|
@ -323,16 +316,14 @@ rfb_decoder_state_wait_for_security (RfbDecoder * decoder)
|
|||
* above.
|
||||
*/
|
||||
if (IS_VERSION_3_3 (decoder)) {
|
||||
buffer = rfb_decoder_read (decoder, 4);
|
||||
rfb_decoder_read (decoder, 4);
|
||||
|
||||
decoder->security_type = RFB_GET_UINT32 (buffer);
|
||||
decoder->security_type = RFB_GET_UINT32 (decoder->data);
|
||||
GST_DEBUG ("security = %d", decoder->security_type);
|
||||
|
||||
g_return_val_if_fail (decoder->security_type < 3, FALSE);
|
||||
g_return_val_if_fail (decoder->security_type != SECURITY_FAIL,
|
||||
rfb_decoder_state_reason (decoder));
|
||||
g_free (buffer);
|
||||
buffer = NULL;
|
||||
} else {
|
||||
/* \TODO Add behavoir for the rfb 3.7 and 3.8 servers */
|
||||
GST_WARNING ("Other versions are not yet supported");
|
||||
|
@ -360,10 +351,9 @@ rfb_decoder_state_wait_for_security (RfbDecoder * decoder)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
buffer = rfb_decoder_read (decoder, 16);
|
||||
vncEncryptBytes ((unsigned char *) buffer, decoder->password);
|
||||
rfb_decoder_send (decoder, buffer, 16);
|
||||
g_free (buffer);
|
||||
rfb_decoder_read (decoder, 16);
|
||||
vncEncryptBytes ((unsigned char *) decoder->data, decoder->password);
|
||||
rfb_decoder_send (decoder, decoder->data, 16);
|
||||
|
||||
GST_DEBUG ("Encrypted challenge send to server");
|
||||
|
||||
|
@ -384,10 +374,8 @@ rfb_decoder_state_wait_for_security (RfbDecoder * decoder)
|
|||
static gboolean
|
||||
rfb_decoder_state_security_result (RfbDecoder * decoder)
|
||||
{
|
||||
guint8 *buffer = NULL;
|
||||
|
||||
buffer = rfb_decoder_read (decoder, 4);
|
||||
if (RFB_GET_UINT32 (buffer) != 0) {
|
||||
rfb_decoder_read (decoder, 4);
|
||||
if (RFB_GET_UINT32 (decoder->data) != 0) {
|
||||
GST_WARNING ("Security handshaking failed");
|
||||
if (IS_VERSION_3_8 (decoder)) {
|
||||
decoder->state = rfb_decoder_state_reason;
|
||||
|
@ -440,6 +428,8 @@ rfb_decoder_state_set_encodings (RfbDecoder * decoder)
|
|||
|
||||
GST_DEBUG ("entered set encodings");
|
||||
|
||||
encoder_list =
|
||||
g_slist_append (encoder_list, GUINT_TO_POINTER (ENCODING_TYPE_HEXTILE));
|
||||
encoder_list =
|
||||
g_slist_append (encoder_list, GUINT_TO_POINTER (ENCODING_TYPE_CORRE));
|
||||
encoder_list =
|
||||
|
@ -480,23 +470,22 @@ rfb_decoder_state_send_client_initialisation (RfbDecoder * decoder)
|
|||
static gboolean
|
||||
rfb_decoder_state_wait_for_server_initialisation (RfbDecoder * decoder)
|
||||
{
|
||||
guint8 *buffer = NULL;
|
||||
guint32 name_length;
|
||||
|
||||
buffer = rfb_decoder_read (decoder, 24);
|
||||
rfb_decoder_read (decoder, 24);
|
||||
|
||||
decoder->width = RFB_GET_UINT16 (buffer + 0);
|
||||
decoder->height = RFB_GET_UINT16 (buffer + 2);
|
||||
decoder->bpp = RFB_GET_UINT8 (buffer + 4);
|
||||
decoder->depth = RFB_GET_UINT8 (buffer + 5);
|
||||
decoder->big_endian = RFB_GET_UINT8 (buffer + 6);
|
||||
decoder->true_colour = RFB_GET_UINT8 (buffer + 7);
|
||||
decoder->red_max = RFB_GET_UINT16 (buffer + 8);
|
||||
decoder->green_max = RFB_GET_UINT16 (buffer + 10);
|
||||
decoder->blue_max = RFB_GET_UINT16 (buffer + 12);
|
||||
decoder->red_shift = RFB_GET_UINT8 (buffer + 14);
|
||||
decoder->green_shift = RFB_GET_UINT8 (buffer + 15);
|
||||
decoder->blue_shift = RFB_GET_UINT8 (buffer + 16);
|
||||
decoder->width = RFB_GET_UINT16 (decoder->data + 0);
|
||||
decoder->height = RFB_GET_UINT16 (decoder->data + 2);
|
||||
decoder->bpp = RFB_GET_UINT8 (decoder->data + 4);
|
||||
decoder->depth = RFB_GET_UINT8 (decoder->data + 5);
|
||||
decoder->big_endian = RFB_GET_UINT8 (decoder->data + 6);
|
||||
decoder->true_colour = RFB_GET_UINT8 (decoder->data + 7);
|
||||
decoder->red_max = RFB_GET_UINT16 (decoder->data + 8);
|
||||
decoder->green_max = RFB_GET_UINT16 (decoder->data + 10);
|
||||
decoder->blue_max = RFB_GET_UINT16 (decoder->data + 12);
|
||||
decoder->red_shift = RFB_GET_UINT8 (decoder->data + 14);
|
||||
decoder->green_shift = RFB_GET_UINT8 (decoder->data + 15);
|
||||
decoder->blue_shift = RFB_GET_UINT8 (decoder->data + 16);
|
||||
|
||||
GST_DEBUG ("Server Initialization");
|
||||
GST_DEBUG ("width = %d", decoder->width);
|
||||
|
@ -512,12 +501,11 @@ rfb_decoder_state_wait_for_server_initialisation (RfbDecoder * decoder)
|
|||
GST_DEBUG ("green_shift= %d", decoder->green_shift);
|
||||
GST_DEBUG ("blue_shift = %d", decoder->blue_shift);
|
||||
|
||||
name_length = RFB_GET_UINT32 (buffer + 20);
|
||||
name_length = RFB_GET_UINT32 (decoder->data + 20);
|
||||
|
||||
buffer = rfb_decoder_read (decoder, name_length);
|
||||
rfb_decoder_read (decoder, name_length);
|
||||
|
||||
decoder->name = g_strndup ((gchar *) (buffer), name_length);
|
||||
g_free (buffer);
|
||||
decoder->name = g_strndup ((gchar *) (decoder->data), name_length);
|
||||
GST_DEBUG ("name = %s", decoder->name);
|
||||
|
||||
/* check if we need cropping */
|
||||
|
@ -558,13 +546,12 @@ rfb_decoder_state_wait_for_server_initialisation (RfbDecoder * decoder)
|
|||
static gboolean
|
||||
rfb_decoder_state_normal (RfbDecoder * decoder)
|
||||
{
|
||||
guint8 *buffer;
|
||||
gint message_type;
|
||||
|
||||
GST_DEBUG ("decoder_state_normal");
|
||||
|
||||
buffer = rfb_decoder_read (decoder, 1);
|
||||
message_type = RFB_GET_UINT8 (buffer);
|
||||
rfb_decoder_read (decoder, 1);
|
||||
message_type = RFB_GET_UINT8 (decoder->data);
|
||||
|
||||
switch (message_type) {
|
||||
case MESSAGE_TYPE_FRAMEBUFFER_UPDATE:
|
||||
|
@ -585,18 +572,16 @@ rfb_decoder_state_normal (RfbDecoder * decoder)
|
|||
g_critical ("unknown message type %d", message_type);
|
||||
}
|
||||
|
||||
g_free (buffer);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
rfb_decoder_state_framebuffer_update (RfbDecoder * decoder)
|
||||
{
|
||||
guint8 *buffer;
|
||||
|
||||
buffer = rfb_decoder_read (decoder, 3);
|
||||
rfb_decoder_read (decoder, 3);
|
||||
|
||||
decoder->n_rects = RFB_GET_UINT16 (buffer + 1);
|
||||
decoder->n_rects = RFB_GET_UINT16 (decoder->data + 1);
|
||||
GST_DEBUG ("Number of rectangles : %d", decoder->n_rects);
|
||||
|
||||
decoder->state = rfb_decoder_state_framebuffer_update_rectangle;
|
||||
|
@ -607,17 +592,16 @@ rfb_decoder_state_framebuffer_update (RfbDecoder * decoder)
|
|||
static gboolean
|
||||
rfb_decoder_state_framebuffer_update_rectangle (RfbDecoder * decoder)
|
||||
{
|
||||
guint8 *buffer;
|
||||
gint x, y, w, h;
|
||||
gint encoding;
|
||||
|
||||
buffer = rfb_decoder_read (decoder, 12);
|
||||
rfb_decoder_read (decoder, 12);
|
||||
|
||||
x = RFB_GET_UINT16 (buffer + 0) - decoder->offset_x;
|
||||
y = RFB_GET_UINT16 (buffer + 2) - decoder->offset_y;
|
||||
w = RFB_GET_UINT16 (buffer + 4);
|
||||
h = RFB_GET_UINT16 (buffer + 6);
|
||||
encoding = RFB_GET_UINT32 (buffer + 8);
|
||||
x = RFB_GET_UINT16 (decoder->data + 0) - decoder->offset_x;
|
||||
y = RFB_GET_UINT16 (decoder->data + 2) - decoder->offset_y;
|
||||
w = RFB_GET_UINT16 (decoder->data + 4);
|
||||
h = RFB_GET_UINT16 (decoder->data + 6);
|
||||
encoding = RFB_GET_UINT32 (decoder->data + 8);
|
||||
|
||||
GST_DEBUG ("update recieved");
|
||||
GST_DEBUG ("x:%d y:%d", x, y);
|
||||
|
@ -637,11 +621,13 @@ rfb_decoder_state_framebuffer_update_rectangle (RfbDecoder * decoder)
|
|||
case ENCODING_TYPE_CORRE:
|
||||
rfb_decoder_corre_encoding (decoder, x, y, w, h);
|
||||
break;
|
||||
case ENCODING_TYPE_HEXTILE:
|
||||
rfb_decoder_hextile_encoding (decoder, x, y, w, h);
|
||||
break;
|
||||
default:
|
||||
g_critical ("unimplemented encoding\n");
|
||||
break;
|
||||
}
|
||||
g_free (buffer);
|
||||
decoder->n_rects--;
|
||||
if (decoder->n_rects == 0) {
|
||||
decoder->state = NULL;
|
||||
|
@ -656,26 +642,24 @@ rfb_decoder_raw_encoding (RfbDecoder * decoder, gint start_x, gint start_y,
|
|||
gint rect_w, gint rect_h)
|
||||
{
|
||||
gint size;
|
||||
guint8 *frame, *buffer, *p;
|
||||
guint8 *frame, *p;
|
||||
guint32 raw_line_size;
|
||||
|
||||
raw_line_size = rect_w * decoder->bytespp;
|
||||
size = rect_h * raw_line_size;
|
||||
GST_DEBUG ("Reading %d bytes", size);
|
||||
buffer = rfb_decoder_read (decoder, size);
|
||||
GST_DEBUG ("Reading %d bytes (%dx%d)", size, rect_w, rect_h);
|
||||
rfb_decoder_read (decoder, size);
|
||||
|
||||
frame =
|
||||
decoder->frame + (((start_y * decoder->rect_width) +
|
||||
start_x) * decoder->bytespp);
|
||||
p = buffer;
|
||||
p = decoder->data;
|
||||
|
||||
while (rect_h--) {
|
||||
memcpy (frame, p, raw_line_size);
|
||||
p += raw_line_size;
|
||||
frame += decoder->line_size;
|
||||
}
|
||||
|
||||
g_free (buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -684,14 +668,13 @@ rfb_decoder_copyrect_encoding (RfbDecoder * decoder, gint start_x, gint start_y,
|
|||
{
|
||||
guint16 src_x, src_y;
|
||||
gint line_width, copyrect_width;
|
||||
guint8 *buffer;
|
||||
guint8 *src, *dst;
|
||||
|
||||
buffer = rfb_decoder_read (decoder, 4);
|
||||
rfb_decoder_read (decoder, 4);
|
||||
|
||||
/* don't forget the offset */
|
||||
src_x = RFB_GET_UINT16 (buffer) - decoder->offset_x;
|
||||
src_y = RFB_GET_UINT16 (buffer + 2) - decoder->offset_y;
|
||||
src_x = RFB_GET_UINT16 (decoder->data) - decoder->offset_x;
|
||||
src_y = RFB_GET_UINT16 (decoder->data + 2) - decoder->offset_y;
|
||||
GST_DEBUG ("Copyrect from %d %d", src_x, src_y);
|
||||
|
||||
copyrect_width = rect_w * decoder->bytespp;
|
||||
|
@ -708,8 +691,6 @@ rfb_decoder_copyrect_encoding (RfbDecoder * decoder, gint start_x, gint start_y,
|
|||
src += line_width;
|
||||
dst += line_width;
|
||||
}
|
||||
|
||||
g_free (buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -735,14 +716,12 @@ static void
|
|||
rfb_decoder_rre_encoding (RfbDecoder * decoder, gint start_x, gint start_y,
|
||||
gint rect_w, gint rect_h)
|
||||
{
|
||||
guint8 *buffer;
|
||||
guint32 number_of_rectangles, color;
|
||||
guint16 x, y, w, h;
|
||||
|
||||
buffer = rfb_decoder_read (decoder, 4 + decoder->bytespp);
|
||||
number_of_rectangles = RFB_GET_UINT32 (buffer);
|
||||
color = GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (buffer + 4)));
|
||||
g_free (buffer);
|
||||
rfb_decoder_read (decoder, 4 + decoder->bytespp);
|
||||
number_of_rectangles = RFB_GET_UINT32 (decoder->data);
|
||||
color = GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (decoder->data + 4)));
|
||||
|
||||
GST_DEBUG ("number of rectangles :%d", number_of_rectangles);
|
||||
|
||||
|
@ -751,17 +730,15 @@ rfb_decoder_rre_encoding (RfbDecoder * decoder, gint start_x, gint start_y,
|
|||
|
||||
while (number_of_rectangles--) {
|
||||
|
||||
buffer = rfb_decoder_read (decoder, decoder->bytespp + 8);
|
||||
color = GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (buffer)));
|
||||
x = RFB_GET_UINT16 (buffer + decoder->bytespp);
|
||||
y = RFB_GET_UINT16 (buffer + decoder->bytespp + 2);
|
||||
w = RFB_GET_UINT16 (buffer + decoder->bytespp + 4);
|
||||
h = RFB_GET_UINT16 (buffer + decoder->bytespp + 6);
|
||||
rfb_decoder_read (decoder, decoder->bytespp + 8);
|
||||
color = GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (decoder->data)));
|
||||
x = RFB_GET_UINT16 (decoder->data + decoder->bytespp);
|
||||
y = RFB_GET_UINT16 (decoder->data + decoder->bytespp + 2);
|
||||
w = RFB_GET_UINT16 (decoder->data + decoder->bytespp + 4);
|
||||
h = RFB_GET_UINT16 (decoder->data + decoder->bytespp + 6);
|
||||
|
||||
/* draw the rectangle in the foreground */
|
||||
rfb_decoder_fill_rectangle (decoder, start_x + x, start_y + y, w, h, color);
|
||||
|
||||
g_free (buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -769,14 +746,13 @@ static void
|
|||
rfb_decoder_corre_encoding (RfbDecoder * decoder, gint start_x, gint start_y,
|
||||
gint rect_w, gint rect_h)
|
||||
{
|
||||
guint8 *buffer;
|
||||
guint32 number_of_rectangles, color;
|
||||
guint8 x, y, w, h;
|
||||
|
||||
buffer = rfb_decoder_read (decoder, 4 + decoder->bytespp);
|
||||
number_of_rectangles = RFB_GET_UINT32 (buffer);
|
||||
color = GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (buffer + 4)));
|
||||
g_free (buffer);
|
||||
rfb_decoder_read (decoder, 4 + decoder->bytespp);
|
||||
number_of_rectangles = RFB_GET_UINT32 (decoder->data);
|
||||
color = GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (decoder->data + 4)));
|
||||
g_free (decoder->data);
|
||||
|
||||
GST_DEBUG ("number of rectangles :%d", number_of_rectangles);
|
||||
|
||||
|
@ -785,17 +761,97 @@ rfb_decoder_corre_encoding (RfbDecoder * decoder, gint start_x, gint start_y,
|
|||
|
||||
while (number_of_rectangles--) {
|
||||
|
||||
buffer = rfb_decoder_read (decoder, decoder->bytespp + 8);
|
||||
color = GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (buffer)));
|
||||
x = RFB_GET_UINT8 (buffer + decoder->bytespp);
|
||||
y = RFB_GET_UINT8 (buffer + decoder->bytespp + 1);
|
||||
w = RFB_GET_UINT8 (buffer + decoder->bytespp + 2);
|
||||
h = RFB_GET_UINT8 (buffer + decoder->bytespp + 3);
|
||||
rfb_decoder_read (decoder, decoder->bytespp + 4);
|
||||
color = GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (decoder->data)));
|
||||
x = RFB_GET_UINT8 (decoder->data + decoder->bytespp);
|
||||
y = RFB_GET_UINT8 (decoder->data + decoder->bytespp + 1);
|
||||
w = RFB_GET_UINT8 (decoder->data + decoder->bytespp + 2);
|
||||
h = RFB_GET_UINT8 (decoder->data + decoder->bytespp + 3);
|
||||
|
||||
/* draw the rectangle in the foreground */
|
||||
rfb_decoder_fill_rectangle (decoder, start_x + x, start_y + y, w, h, color);
|
||||
|
||||
g_free (buffer);
|
||||
g_free (decoder->data);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rfb_decoder_hextile_encoding (RfbDecoder * decoder, gint start_x, gint start_y,
|
||||
gint rect_w, gint rect_h)
|
||||
{
|
||||
gint32 x, x_count, x_end, x_max, x_max_16;
|
||||
gint32 y, y_count, y_end, y_max, y_max_16;
|
||||
guint8 subencoding, nr_subrect, xy, wh;
|
||||
guint32 background, foreground;
|
||||
|
||||
x_end = rect_w % 16;
|
||||
x_count = rect_w / 16 + (x_end > 0 ? 1 : 0);
|
||||
y_end = rect_h % 16;
|
||||
y_count = rect_h / 16 + (y_end > 0 ? 1 : 0);
|
||||
x_max = start_x + rect_w;
|
||||
y_max = start_y + rect_h;
|
||||
x_max_16 = x_max - 16;
|
||||
y_max_16 = y_max - 16;
|
||||
|
||||
for (y = start_y; y < y_max; y += 16) {
|
||||
for (x = start_x; x < x_max; x += 16) {
|
||||
|
||||
rfb_decoder_read (decoder, 1);
|
||||
subencoding = RFB_GET_UINT8 (decoder->data);
|
||||
|
||||
if (subencoding & SUBENCODING_RAW) {
|
||||
rfb_decoder_raw_encoding (decoder, x, y,
|
||||
(x <= x_max_16 ? 16 : x_end), (y <= y_max_16 ? 16 : y_end));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (subencoding & SUBENCODING_BACKGROUND) {
|
||||
rfb_decoder_read (decoder, decoder->bytespp);
|
||||
background = GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (decoder->data)));
|
||||
}
|
||||
rfb_decoder_fill_rectangle (decoder, x, y,
|
||||
(x <= x_max_16 ? 16 : x_end), (y <= y_max_16 ? 16 : y_end),
|
||||
background);
|
||||
|
||||
if (subencoding & SUBENCODING_FOREGROUND) {
|
||||
rfb_decoder_read (decoder, decoder->bytespp);
|
||||
foreground = GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (decoder->data)));
|
||||
}
|
||||
|
||||
if (subencoding & SUBENCODING_ANYSUBRECTS) {
|
||||
rfb_decoder_read (decoder, 1);
|
||||
nr_subrect = RFB_GET_UINT8 (decoder->data);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (subencoding & SUBENCODING_SUBRECTSCOLORED) {
|
||||
guint offset = 0;
|
||||
|
||||
rfb_decoder_read (decoder, nr_subrect * (2 + decoder->bytespp));
|
||||
|
||||
while (nr_subrect--) {
|
||||
foreground =
|
||||
GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (decoder->data + offset)));
|
||||
offset += decoder->bytespp;
|
||||
xy = RFB_GET_UINT8 (decoder->data + offset++);
|
||||
wh = RFB_GET_UINT8 (decoder->data + offset++);
|
||||
rfb_decoder_fill_rectangle (decoder, x + (xy >> 4), y + (xy & 0xF),
|
||||
1 + (wh >> 4), 1 + (wh & 0xF), foreground);
|
||||
}
|
||||
} else {
|
||||
guint offset = 0;
|
||||
|
||||
rfb_decoder_read (decoder, 2 * nr_subrect);
|
||||
|
||||
while (nr_subrect--) {
|
||||
xy = RFB_GET_UINT8 (decoder->data + offset++);
|
||||
wh = RFB_GET_UINT8 (decoder->data + offset++);
|
||||
rfb_decoder_fill_rectangle (decoder, x + (xy >> 4), y + (xy & 0xF),
|
||||
1 + (wh >> 4), 1 + (wh & 0xF), foreground);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -810,17 +866,15 @@ rfb_decoder_state_set_colour_map_entries (RfbDecoder * decoder)
|
|||
static gboolean
|
||||
rfb_decoder_state_server_cut_text (RfbDecoder * decoder)
|
||||
{
|
||||
guint8 *buffer;
|
||||
gint cut_text_length;
|
||||
|
||||
/* 3 bytes padding, 4 bytes cut_text_length */
|
||||
buffer = rfb_decoder_read (decoder, 7);
|
||||
cut_text_length = RFB_GET_UINT32 (buffer + 3);
|
||||
g_free (buffer);
|
||||
rfb_decoder_read (decoder, 7);
|
||||
cut_text_length = RFB_GET_UINT32 (decoder->data + 3);
|
||||
|
||||
buffer = rfb_decoder_read (decoder, cut_text_length);
|
||||
GST_DEBUG ("rfb_decoder_state_server_cut_text: throw away '%s'", buffer);
|
||||
g_free (buffer);
|
||||
rfb_decoder_read (decoder, cut_text_length);
|
||||
GST_DEBUG ("rfb_decoder_state_server_cut_text: throw away '%s'",
|
||||
decoder->data);
|
||||
|
||||
decoder->state = rfb_decoder_state_normal;
|
||||
return TRUE;
|
||||
|
|
|
@ -21,6 +21,13 @@ G_BEGIN_DECLS enum
|
|||
#define ENCODING_TYPE_COPYRECT 1
|
||||
#define ENCODING_TYPE_RRE 2
|
||||
#define ENCODING_TYPE_CORRE 4
|
||||
#define ENCODING_TYPE_HEXTILE 5
|
||||
|
||||
#define SUBENCODING_RAW 1
|
||||
#define SUBENCODING_BACKGROUND 2
|
||||
#define SUBENCODING_FOREGROUND 4
|
||||
#define SUBENCODING_ANYSUBRECTS 8
|
||||
#define SUBENCODING_SUBRECTSCOLORED 16
|
||||
|
||||
typedef struct _RfbDecoder RfbDecoder;
|
||||
|
||||
|
@ -33,6 +40,8 @@ struct _RfbDecoder
|
|||
|
||||
gint fd;
|
||||
|
||||
guint8 *data;
|
||||
guint32 data_len;
|
||||
gpointer decoder_private;
|
||||
guint8 *frame;
|
||||
guint8 *prev_frame;
|
||||
|
|
Loading…
Reference in a new issue