From 519359a8230df9a72e83ca53cd271c024004110a Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Thu, 15 Dec 2016 00:39:13 -0800 Subject: fixes for bitmap update --- libxrdp/libxrdp.c | 167 +++++++++++++++++++++++++++++++++++++++++++--------- libxrdp/xrdp_caps.c | 1 + 2 files changed, 139 insertions(+), 29 deletions(-) diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c index c3763bf5..b03db073 100644 --- a/libxrdp/libxrdp.c +++ b/libxrdp/libxrdp.c @@ -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; } 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; } - 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 = 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,67 @@ 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 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); + } + for (k = 0; k < e; k++) + { + out_uint8s(s, 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); + } + for (k = 0; k < e; k++) + { + out_uint8s(s, 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); + } + for (k = 0; k < e; k++) + { + out_uint8s(s, 4); + } + } + break; + default: /* 8 bpp */ + for (j = 0; j < lines_sending; j++) + { + q = q - line_bytes; + out_uint8a(s, q, line_bytes); + out_uint8s(s, e * Bpp); + } + break; } s_mark_end(s); diff --git a/libxrdp/xrdp_caps.c b/libxrdp/xrdp_caps.c index 8d5250d5..35778b5b 100644 --- a/libxrdp/xrdp_caps.c +++ b/libxrdp/xrdp_caps.c @@ -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 */ -- cgit v1.2.1 From 81e72fc99c25132e6ed868a17def3823d8918ed4 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Thu, 15 Dec 2016 14:47:37 -0800 Subject: code cleanup, add some comments --- libxrdp/libxrdp.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c index b03db073..dbffcd58 100644 --- a/libxrdp/libxrdp.c +++ b/libxrdp/libxrdp.c @@ -439,7 +439,7 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height, while (i > 0) { - LLOGLN(10, ("libxrdp_send_bitmap: i %d", i)); + LLOGLN(10, ("libxrdp_send_bitmap: i %d", i)); total_bufsize = 0; num_updates = 0; @@ -506,7 +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; + total_bufsize += 18; /* bytes since pop layer */ } else { @@ -518,7 +518,7 @@ 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; + total_bufsize += 26; /* bytes since pop layer */ } LLOGLN(10, ("libxrdp_send_bitmap: decompressed pixels %d " @@ -571,7 +571,7 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height, while (i < total_lines) { - lines_sending = (MAX_BITMAP_BUF_SIZE - 100) / (line_pad_bytes); + lines_sending = (MAX_BITMAP_BUF_SIZE - 100) / line_pad_bytes; if (i + lines_sending > total_lines) { @@ -584,7 +584,7 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height, break; } - p = p + server_line_bytes * lines_sending; + 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 */ -- cgit v1.2.1 From 1cf7f72f953ff52af3e07cd1b25f3bcdd960c4ea Mon Sep 17 00:00:00 2001 From: Koichiro IWAO Date: Fri, 16 Dec 2016 13:25:47 +0900 Subject: CI: correct pixman package name --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cffd98c6..baf038ee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ addons: - libmp3lame-dev - libx11-dev - libxrandr-dev - - libpixman-dev + - libpixman-1-dev - nasm # x11rdp #- flex -- cgit v1.2.1 From 74ec00a6a6bcb6b17dbfa4a979ac0d0e0d42d401 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Thu, 15 Dec 2016 21:52:05 -0800 Subject: some code cleanup --- libxrdp/libxrdp.c | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c index dbffcd58..ba2b04c6 100644 --- a/libxrdp/libxrdp.c +++ b/libxrdp/libxrdp.c @@ -601,6 +601,14 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height, switch (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++) @@ -611,10 +619,7 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height, pixel = *((tui16*)(q + k * 2)); out_uint16_le(s, pixel); } - for (k = 0; k < e; k++) - { - out_uint8s(s, 2); - } + out_uint8s(s, e * 2); } break; case 24: @@ -628,10 +633,7 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height, out_uint8(s, pixel >> 8); out_uint8(s, pixel >> 16); } - for (k = 0; k < e; k++) - { - out_uint8s(s, 3); - } + out_uint8s(s, e * 3); } break; case 32: @@ -643,18 +645,7 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height, pixel = *((int*)(q + k * 4)); out_uint32_le(s, pixel); } - for (k = 0; k < e; k++) - { - out_uint8s(s, 4); - } - } - break; - default: /* 8 bpp */ - for (j = 0; j < lines_sending; j++) - { - q = q - line_bytes; - out_uint8a(s, q, line_bytes); - out_uint8s(s, e * Bpp); + out_uint8s(s, e * 4); } break; } -- cgit v1.2.1