Merge pull request #550 from jsorg71/bitmap_update
fixes for bitmap update
This commit is contained in:
commit
1753f6317c
@ -27,6 +27,8 @@
|
||||
#define LLOGLN(_level, _args) \
|
||||
do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
|
||||
|
||||
#define MAX_BITMAP_BUF_SIZE (16 * 1024) /* 16K */
|
||||
|
||||
/******************************************************************************/
|
||||
struct xrdp_session *EXPORT_CC
|
||||
libxrdp_init(tbus id, struct trans *trans)
|
||||
@ -373,15 +375,15 @@ libxrdp_send_bell(struct xrdp_session *session)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
int EXPORT_CC
|
||||
libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
|
||||
int bpp, char *data, int x, int y, int cx, int cy)
|
||||
{
|
||||
int line_size = 0;
|
||||
int line_bytes = 0;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int k;
|
||||
int total_lines = 0;
|
||||
int lines_sending = 0;
|
||||
int Bpp = 0;
|
||||
@ -389,27 +391,43 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
|
||||
int bufsize = 0;
|
||||
int total_bufsize = 0;
|
||||
int num_updates = 0;
|
||||
int line_pad_bytes;
|
||||
int server_line_bytes;
|
||||
char *p_num_updates = (char *)NULL;
|
||||
char *p = (char *)NULL;
|
||||
char *q = (char *)NULL;
|
||||
struct stream *s = (struct stream *)NULL;
|
||||
struct stream *temp_s = (struct stream *)NULL;
|
||||
tui32 pixel;
|
||||
|
||||
DEBUG(("libxrdp_send_bitmap sending bitmap"));
|
||||
LLOGLN(10, ("libxrdp_send_bitmap: sending bitmap"));
|
||||
Bpp = (bpp + 7) / 8;
|
||||
e = width % 4;
|
||||
|
||||
if (e != 0)
|
||||
e = (4 - width) & 3;
|
||||
switch (bpp)
|
||||
{
|
||||
e = 4 - e;
|
||||
case 15:
|
||||
case 16:
|
||||
server_line_bytes = width * 2;
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
server_line_bytes = width * 4;
|
||||
break;
|
||||
default: /* 8 bpp */
|
||||
server_line_bytes = width;
|
||||
break;
|
||||
}
|
||||
line_bytes = width * Bpp;
|
||||
line_pad_bytes = line_bytes + e * Bpp;
|
||||
|
||||
line_size = width * Bpp;
|
||||
LLOGLN(10, ("libxrdp_send_bitmap: bpp %d Bpp %d line_bytes %d "
|
||||
"server_line_bytes %d", bpp, Bpp, line_bytes, server_line_bytes));
|
||||
make_stream(s);
|
||||
init_stream(s, 8192);
|
||||
init_stream(s, MAX_BITMAP_BUF_SIZE);
|
||||
|
||||
if (session->client_info->use_bitmap_comp)
|
||||
{
|
||||
LLOGLN(10, ("libxrdp_send_bitmap: compression"));
|
||||
make_stream(temp_s);
|
||||
init_stream(temp_s, 65536);
|
||||
i = 0;
|
||||
@ -421,6 +439,8 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
|
||||
|
||||
while (i > 0)
|
||||
{
|
||||
LLOGLN(10, ("libxrdp_send_bitmap: i %d", i));
|
||||
|
||||
total_bufsize = 0;
|
||||
num_updates = 0;
|
||||
xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
|
||||
@ -440,10 +460,26 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
|
||||
}
|
||||
|
||||
p = s->p;
|
||||
lines_sending = xrdp_bitmap_compress(data, width, height,
|
||||
s, bpp,
|
||||
4096 - total_bufsize,
|
||||
i - 1, temp_s, e);
|
||||
|
||||
if (bpp > 24)
|
||||
{
|
||||
LLOGLN(10, ("libxrdp_send_bitmap: 32 bpp"));
|
||||
lines_sending = xrdp_bitmap32_compress(data, width, height,
|
||||
s, 32,
|
||||
(MAX_BITMAP_BUF_SIZE - 100) - total_bufsize,
|
||||
i - 1, temp_s, e, 0x10);
|
||||
LLOGLN(10, ("libxrdp_send_bitmap: i %d lines_sending %d",
|
||||
i, lines_sending));
|
||||
}
|
||||
else
|
||||
{
|
||||
lines_sending = xrdp_bitmap_compress(data, width, height,
|
||||
s, bpp,
|
||||
(MAX_BITMAP_BUF_SIZE - 100) - total_bufsize,
|
||||
i - 1, temp_s, e);
|
||||
LLOGLN(10, ("libxrdp_send_bitmap: i %d lines_sending %d",
|
||||
i, lines_sending));
|
||||
}
|
||||
|
||||
if (lines_sending == 0)
|
||||
{
|
||||
@ -470,6 +506,7 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
|
||||
out_uint16_le(s, bufsize); /* compressed size */
|
||||
j = (width + e) * Bpp;
|
||||
j = j * lines_sending;
|
||||
total_bufsize += 18; /* bytes since pop layer */
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -481,31 +518,42 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
|
||||
out_uint16_le(s, j); /* line size */
|
||||
j = j * lines_sending;
|
||||
out_uint16_le(s, j); /* final size */
|
||||
total_bufsize += 26; /* bytes since pop layer */
|
||||
}
|
||||
|
||||
if (j > 32768)
|
||||
LLOGLN(10, ("libxrdp_send_bitmap: decompressed pixels %d "
|
||||
"decompressed bytes %d compressed bytes %d",
|
||||
lines_sending * (width + e),
|
||||
line_pad_bytes * lines_sending, bufsize));
|
||||
|
||||
if (j > MAX_BITMAP_BUF_SIZE)
|
||||
{
|
||||
g_writeln("error, decompressed size too big: %d bytes", j);
|
||||
LLOGLN(0, ("libxrdp_send_bitmap: error, decompressed "
|
||||
"size too big: %d bytes", j));
|
||||
}
|
||||
|
||||
if (bufsize > 8192)
|
||||
if (bufsize > MAX_BITMAP_BUF_SIZE)
|
||||
{
|
||||
g_writeln("error, compressed size too big: %d bytes", bufsize);
|
||||
LLOGLN(0, ("libxrdp_send_bitmap: error, compressed size "
|
||||
"too big: %d bytes", bufsize));
|
||||
}
|
||||
|
||||
s->p = s->end;
|
||||
}
|
||||
while (total_bufsize < 4096 && i > 0);
|
||||
while (total_bufsize < MAX_BITMAP_BUF_SIZE && i > 0);
|
||||
|
||||
LLOGLN(10, ("libxrdp_send_bitmap: num_updates %d total_bufsize %d",
|
||||
num_updates, total_bufsize));
|
||||
|
||||
p_num_updates[0] = num_updates;
|
||||
p_num_updates[1] = num_updates >> 8;
|
||||
xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s,
|
||||
RDP_DATA_PDU_UPDATE);
|
||||
|
||||
if (total_bufsize > 8192)
|
||||
if (total_bufsize > MAX_BITMAP_BUF_SIZE)
|
||||
{
|
||||
g_writeln("error, total compressed size too big: %d bytes",
|
||||
total_bufsize);
|
||||
LLOGLN(0, ("libxrdp_send_bitmap: error, total compressed "
|
||||
"size too big: %d bytes", total_bufsize));
|
||||
}
|
||||
}
|
||||
|
||||
@ -513,22 +561,30 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
|
||||
}
|
||||
else
|
||||
{
|
||||
LLOGLN(10, ("libxrdp_send_bitmap: no compression"));
|
||||
total_lines = height;
|
||||
i = 0;
|
||||
p = data;
|
||||
|
||||
if (line_size > 0 && total_lines > 0)
|
||||
if (line_bytes > 0 && total_lines > 0)
|
||||
{
|
||||
while (i < total_lines)
|
||||
{
|
||||
lines_sending = 4096 / (line_size + e * Bpp);
|
||||
|
||||
lines_sending = (MAX_BITMAP_BUF_SIZE - 100) / line_pad_bytes;
|
||||
|
||||
if (i + lines_sending > total_lines)
|
||||
{
|
||||
lines_sending = total_lines - i;
|
||||
}
|
||||
|
||||
p = p + line_size * lines_sending;
|
||||
if (lines_sending == 0)
|
||||
{
|
||||
LLOGLN(0, ("libxrdp_send_bitmap: error, lines_sending == zero"));
|
||||
break;
|
||||
}
|
||||
|
||||
p += server_line_bytes * lines_sending;
|
||||
xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
|
||||
out_uint16_le(s, RDP_UPDATE_BITMAP);
|
||||
out_uint16_le(s, 1); /* num updates */
|
||||
@ -540,14 +596,58 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
|
||||
out_uint16_le(s, lines_sending);
|
||||
out_uint16_le(s, bpp); /* bpp */
|
||||
out_uint16_le(s, 0); /* compress */
|
||||
out_uint16_le(s, (line_size + e * Bpp) * lines_sending); /* bufsize */
|
||||
out_uint16_le(s, line_pad_bytes * lines_sending); /* bufsize */
|
||||
q = p;
|
||||
|
||||
for (j = 0; j < lines_sending; j++)
|
||||
switch (bpp)
|
||||
{
|
||||
q = q - line_size;
|
||||
out_uint8a(s, q, line_size); /* B_ENDIAN doesn't work here, todo */
|
||||
out_uint8s(s, e * Bpp);
|
||||
case 8:
|
||||
for (j = 0; j < lines_sending; j++)
|
||||
{
|
||||
q = q - line_bytes;
|
||||
out_uint8a(s, q, line_bytes);
|
||||
out_uint8s(s, e);
|
||||
}
|
||||
break;
|
||||
case 15:
|
||||
case 16:
|
||||
for (j = 0; j < lines_sending; j++)
|
||||
{
|
||||
q = q - server_line_bytes;
|
||||
for (k = 0; k < width; k++)
|
||||
{
|
||||
pixel = *((tui16*)(q + k * 2));
|
||||
out_uint16_le(s, pixel);
|
||||
}
|
||||
out_uint8s(s, e * 2);
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
for (j = 0; j < lines_sending; j++)
|
||||
{
|
||||
q = q - server_line_bytes;
|
||||
for (k = 0; k < width; k++)
|
||||
{
|
||||
pixel = *((tui32*)(q + k * 4));
|
||||
out_uint8(s, pixel);
|
||||
out_uint8(s, pixel >> 8);
|
||||
out_uint8(s, pixel >> 16);
|
||||
}
|
||||
out_uint8s(s, e * 3);
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
for (j = 0; j < lines_sending; j++)
|
||||
{
|
||||
q = q - server_line_bytes;
|
||||
for (k = 0; k < width; k++)
|
||||
{
|
||||
pixel = *((int*)(q + k * 4));
|
||||
out_uint32_le(s, pixel);
|
||||
}
|
||||
out_uint8s(s, e * 4);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
s_mark_end(s);
|
||||
|
@ -80,6 +80,7 @@ xrdp_caps_process_general(struct xrdp_rdp *self, struct stream *s,
|
||||
in_uint8s(s, 6);
|
||||
in_uint16_le(s, extraFlags); /* extraFlags (2 bytes) */
|
||||
|
||||
self->client_info.op1 = extraFlags & NO_BITMAP_COMPRESSION_HDR;
|
||||
/* use_compact_packets is pretty much 'use rdp5' */
|
||||
self->client_info.use_compact_packets = (extraFlags != 0);
|
||||
/* op2 is a boolean to use compact bitmap headers in bitmap cache */
|
||||
|
Loading…
Reference in New Issue
Block a user