Add alternative mppc decompression code with 64kB history buffer from Vahur Sinijärv, and reenable rdp5 (persistent) bitmap cache 2 (64x64)
git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@888 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
parent
d3356457fd
commit
696ea0c4f1
@ -256,8 +256,9 @@ enum RDP_INPUT_DEVICE
|
|||||||
/* Logon flags */
|
/* Logon flags */
|
||||||
#define RDP_LOGON_AUTO 0x0008
|
#define RDP_LOGON_AUTO 0x0008
|
||||||
#define RDP_LOGON_NORMAL 0x0033
|
#define RDP_LOGON_NORMAL 0x0033
|
||||||
#define RDP_COMPRESSION 0x0080
|
#define RDP_LOGON_COMPRESSION 0x0080 /* mppc compression with 8kB histroy buffer */
|
||||||
#define RDP_LOGON_BLOB 0x0100
|
#define RDP_LOGON_BLOB 0x0100
|
||||||
|
#define RDP_LOGON_COMPRESSION2 0x0200 /* rdp5 mppc compression with 64kB history buffer */
|
||||||
#define RDP_LOGON_LEAVE_AUDIO 0x2000
|
#define RDP_LOGON_LEAVE_AUDIO 0x2000
|
||||||
|
|
||||||
#define RDP5_DISABLE_NOTHING 0x00
|
#define RDP5_DISABLE_NOTHING 0x00
|
||||||
@ -269,10 +270,13 @@ enum RDP_INPUT_DEVICE
|
|||||||
#define RDP5_NO_CURSORSETTINGS 0x40 /* disables cursor blinking */
|
#define RDP5_NO_CURSORSETTINGS 0x40 /* disables cursor blinking */
|
||||||
|
|
||||||
/* compression types */
|
/* compression types */
|
||||||
|
#define RDP_MPPC_BIG 0x01
|
||||||
#define RDP_MPPC_COMPRESSED 0x20
|
#define RDP_MPPC_COMPRESSED 0x20
|
||||||
#define RDP_MPPC_RESET 0x40
|
#define RDP_MPPC_RESET 0x40
|
||||||
#define RDP_MPPC_FLUSH 0x80
|
#define RDP_MPPC_FLUSH 0x80
|
||||||
#define RDP_MPPC_DICT_SIZE 8192
|
#define RDP_MPPC_DICT_SIZE 65536
|
||||||
|
|
||||||
|
#define RDP5_COMPRESSED 0x80
|
||||||
|
|
||||||
/* Keymap flags */
|
/* Keymap flags */
|
||||||
#define MapRightShiftMask (1<<0)
|
#define MapRightShiftMask (1<<0)
|
||||||
|
159
mppc.c
159
mppc.c
@ -155,60 +155,131 @@ mppc_expand(uint8 * data, uint32 clen, uint8 ctype, uint32 * roff, uint32 * rlen
|
|||||||
/* decode offset */
|
/* decode offset */
|
||||||
/* length pair */
|
/* length pair */
|
||||||
walker <<= 1;
|
walker <<= 1;
|
||||||
if (--walker_len < 2)
|
if (--walker_len < (ctype & RDP_MPPC_BIG ? 3 : 2))
|
||||||
{
|
{
|
||||||
if (i >= clen)
|
if (i >= clen)
|
||||||
return -1;
|
return -1;
|
||||||
walker |= (data[i++] & 0xff) << (24 - walker_len);
|
walker |= (data[i++] & 0xff) << (24 - walker_len);
|
||||||
walker_len += 8;
|
walker_len += 8;
|
||||||
}
|
}
|
||||||
/* offset decoding where offset len is:
|
|
||||||
-63: 1111 followed by the lower 6 bits of the value
|
if (ctype & RDP_MPPC_BIG)
|
||||||
64-319: 1110 followed by the lower 8 bits of the value ( value - 64 )
|
|
||||||
320-8191: 110 followed by the lower 13 bits of the value ( value - 320 )
|
|
||||||
*/
|
|
||||||
switch (((uint32) walker) >> ((uint32) 30))
|
|
||||||
{
|
{
|
||||||
case 3: /* - 63 */
|
/* offset decoding where offset len is:
|
||||||
if (walker_len < 8)
|
-63: 11111 followed by the lower 6 bits of the value
|
||||||
{
|
64-319: 11110 followed by the lower 8 bits of the value ( value - 64 )
|
||||||
if (i >= clen)
|
320-2367: 1110 followed by lower 11 bits of the value ( value - 320 )
|
||||||
return -1;
|
2368-65535: 110 followed by lower 16 bits of the value ( value - 2368 )
|
||||||
walker |= (data[i++] & 0xff) << (24 - walker_len);
|
*/
|
||||||
walker_len += 8;
|
switch (((uint32) walker) >> ((uint32) 29))
|
||||||
}
|
{
|
||||||
walker <<= 2;
|
case 7: /* - 63 */
|
||||||
match_off = ((uint32) walker) >> ((uint32) 26);
|
for (; walker_len < 9; walker_len += 8)
|
||||||
walker <<= 6;
|
{
|
||||||
walker_len -= 8;
|
if (i >= clen)
|
||||||
break;
|
return -1;
|
||||||
|
walker |= (data[i++] & 0xff) << (24 - walker_len);
|
||||||
|
}
|
||||||
|
walker <<= 3;
|
||||||
|
match_off = ((uint32) walker) >> ((uint32) 26);
|
||||||
|
walker <<= 6;
|
||||||
|
walker_len -= 9;
|
||||||
|
break;
|
||||||
|
|
||||||
case 2: /* 64 - 319 */
|
case 6: /* 64 - 319 */
|
||||||
for (; walker_len < 10; walker_len += 8)
|
for (; walker_len < 11; walker_len += 8)
|
||||||
{
|
{
|
||||||
if (i >= clen)
|
if (i >= clen)
|
||||||
return -1;
|
return -1;
|
||||||
walker |= (data[i++] & 0xff) << (24 - walker_len);
|
walker |= (data[i++] & 0xff) << (24 - walker_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
walker <<= 2;
|
walker <<= 3;
|
||||||
match_off = (((uint32) walker) >> ((uint32) 24)) + 64;
|
match_off = (((uint32) walker) >> ((uint32) 24)) + 64;
|
||||||
walker <<= 8;
|
walker <<= 8;
|
||||||
walker_len -= 10;
|
walker_len -= 11;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: /* 320 - 8191 */
|
case 5:
|
||||||
for (; walker_len < 14; walker_len += 8)
|
case 4: /* 320 - 2367 */
|
||||||
{
|
for (; walker_len < 13; walker_len += 8)
|
||||||
if (i >= clen)
|
{
|
||||||
return -1;
|
if (i >= clen)
|
||||||
walker |= (data[i++] & 0xff) << (24 - walker_len);
|
return -1;
|
||||||
}
|
walker |= (data[i++] & 0xff) << (24 - walker_len);
|
||||||
|
}
|
||||||
|
|
||||||
match_off = (walker >> 18) + 320;
|
walker <<= 2;
|
||||||
walker <<= 14;
|
match_off = (((uint32) walker) >> ((uint32) 21)) + 320;
|
||||||
walker_len -= 14;
|
walker <<= 11;
|
||||||
break;
|
walker_len -= 13;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: /* 2368 - 65535 */
|
||||||
|
for (; walker_len < 17; walker_len += 8)
|
||||||
|
{
|
||||||
|
if (i >= clen)
|
||||||
|
return -1;
|
||||||
|
walker |= (data[i++] & 0xff) << (24 - walker_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
walker <<= 1;
|
||||||
|
match_off = (((uint32) walker) >> ((uint32) 16)) + 2368;
|
||||||
|
walker <<= 16;
|
||||||
|
walker_len -= 17;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* offset decoding where offset len is:
|
||||||
|
-63: 1111 followed by the lower 6 bits of the value
|
||||||
|
64-319: 1110 followed by the lower 8 bits of the value ( value - 64 )
|
||||||
|
320-8191: 110 followed by the lower 13 bits of the value ( value - 320 )
|
||||||
|
*/
|
||||||
|
switch (((uint32) walker) >> ((uint32) 30))
|
||||||
|
{
|
||||||
|
case 3: /* - 63 */
|
||||||
|
if (walker_len < 8)
|
||||||
|
{
|
||||||
|
if (i >= clen)
|
||||||
|
return -1;
|
||||||
|
walker |= (data[i++] & 0xff) << (24 - walker_len);
|
||||||
|
walker_len += 8;
|
||||||
|
}
|
||||||
|
walker <<= 2;
|
||||||
|
match_off = ((uint32) walker) >> ((uint32) 26);
|
||||||
|
walker <<= 6;
|
||||||
|
walker_len -= 8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: /* 64 - 319 */
|
||||||
|
for (; walker_len < 10; walker_len += 8)
|
||||||
|
{
|
||||||
|
if (i >= clen)
|
||||||
|
return -1;
|
||||||
|
walker |= (data[i++] & 0xff) << (24 - walker_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
walker <<= 2;
|
||||||
|
match_off = (((uint32) walker) >> ((uint32) 24)) + 64;
|
||||||
|
walker <<= 8;
|
||||||
|
walker_len -= 10;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: /* 320 - 8191 */
|
||||||
|
for (; walker_len < 14; walker_len += 8)
|
||||||
|
{
|
||||||
|
if (i >= clen)
|
||||||
|
return -1;
|
||||||
|
walker |= (data[i++] & 0xff) << (24 - walker_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
match_off = (walker >> 18) + 320;
|
||||||
|
walker <<= 14;
|
||||||
|
walker_len -= 14;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (walker_len == 0)
|
if (walker_len == 0)
|
||||||
{
|
{
|
||||||
@ -289,7 +360,7 @@ mppc_expand(uint8 * data, uint32 clen, uint8 ctype, uint32 * roff, uint32 * rlen
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* memory areas can overlap - meaning we can't use memXXX functions */
|
/* memory areas can overlap - meaning we can't use memXXX functions */
|
||||||
k = (next_offset - match_off) & (RDP_MPPC_DICT_SIZE - 1);
|
k = (next_offset - match_off) & (ctype & RDP_MPPC_BIG ? 65535 : 8191);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
dict[next_offset++] = dict[k++];
|
dict[next_offset++] = dict[k++];
|
||||||
|
@ -85,7 +85,6 @@ BOOL g_console_session = False;
|
|||||||
BOOL g_numlock_sync = False;
|
BOOL g_numlock_sync = False;
|
||||||
BOOL g_owncolmap = False;
|
BOOL g_owncolmap = False;
|
||||||
BOOL g_ownbackstore = True; /* We can't rely on external BackingStore */
|
BOOL g_ownbackstore = True; /* We can't rely on external BackingStore */
|
||||||
BOOL g_rdp_compression = False;
|
|
||||||
uint32 g_embed_wnd;
|
uint32 g_embed_wnd;
|
||||||
uint32 g_rdp5_performanceflags =
|
uint32 g_rdp5_performanceflags =
|
||||||
RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;
|
RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;
|
||||||
@ -575,8 +574,7 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
case 'z':
|
case 'z':
|
||||||
DEBUG(("rdp compression enabled\n"));
|
DEBUG(("rdp compression enabled\n"));
|
||||||
flags |= RDP_COMPRESSION;
|
flags |= (RDP_LOGON_COMPRESSION | RDP_LOGON_COMPRESSION2);
|
||||||
g_rdp_compression = True;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'x':
|
case 'x':
|
||||||
|
30
rdp.c
30
rdp.c
@ -298,12 +298,6 @@ rdp_send_logon_info(uint32 flags, char *domain, char *user,
|
|||||||
time_t t = time(NULL);
|
time_t t = time(NULL);
|
||||||
time_t tzone;
|
time_t tzone;
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* enable rdp compression */
|
|
||||||
/* some problems still exist with rdp5 */
|
|
||||||
flags |= RDP_COMPRESSION;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!g_use_rdp5 || 1 == g_server_rdp_version)
|
if (!g_use_rdp5 || 1 == g_server_rdp_version)
|
||||||
{
|
{
|
||||||
DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
|
DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
|
||||||
@ -660,34 +654,14 @@ rdp_out_bmpcache_caps(STREAM s)
|
|||||||
static void
|
static void
|
||||||
rdp_out_bmpcache2_caps(STREAM s)
|
rdp_out_bmpcache2_caps(STREAM s)
|
||||||
{
|
{
|
||||||
uint16 cellsize;
|
|
||||||
|
|
||||||
out_uint16_le(s, RDP_CAPSET_BMPCACHE2);
|
out_uint16_le(s, RDP_CAPSET_BMPCACHE2);
|
||||||
out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);
|
out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);
|
||||||
|
|
||||||
out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0); /* version */
|
out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0); /* version */
|
||||||
|
|
||||||
/* Cellsize:
|
out_uint16_be(s, 3); /* number of caches in this set */
|
||||||
01 = 16x16, 02 = 32x32, 03 = 64x64
|
|
||||||
log2(cell size) - 3
|
|
||||||
*/
|
|
||||||
|
|
||||||
cellsize = 0x03;
|
|
||||||
|
|
||||||
if (g_rdp_compression)
|
|
||||||
{
|
|
||||||
switch (g_server_bpp)
|
|
||||||
{
|
|
||||||
case 24:
|
|
||||||
case 16:
|
|
||||||
case 15:
|
|
||||||
cellsize = 0x02;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out_uint16_le(s, (0x0000 | (cellsize << 8))); /* flags? number of caches? */
|
|
||||||
|
|
||||||
|
/* max cell size for cache 0 is 16x16, 1 = 32x32, 2 = 64x64, etc */
|
||||||
out_uint32_le(s, BMPCACHE2_C0_CELLS);
|
out_uint32_le(s, BMPCACHE2_C0_CELLS);
|
||||||
out_uint32_le(s, BMPCACHE2_C1_CELLS);
|
out_uint32_le(s, BMPCACHE2_C1_CELLS);
|
||||||
if (pstcache_init(2))
|
if (pstcache_init(2))
|
||||||
|
6
rdp5.c
6
rdp5.c
@ -45,11 +45,11 @@ rdp5_process(STREAM s)
|
|||||||
while (s->p < s->end)
|
while (s->p < s->end)
|
||||||
{
|
{
|
||||||
in_uint8(s, type);
|
in_uint8(s, type);
|
||||||
if (type & RDP_COMPRESSION)
|
if (type & RDP5_COMPRESSED)
|
||||||
{
|
{
|
||||||
in_uint8(s, ctype);
|
in_uint8(s, ctype);
|
||||||
in_uint16_le(s, length);
|
in_uint16_le(s, length);
|
||||||
type ^= RDP_COMPRESSION;
|
type ^= RDP5_COMPRESSED;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -60,8 +60,6 @@ rdp5_process(STREAM s)
|
|||||||
|
|
||||||
if (ctype & RDP_MPPC_COMPRESSED)
|
if (ctype & RDP_MPPC_COMPRESSED)
|
||||||
{
|
{
|
||||||
if (length > RDP_MPPC_DICT_SIZE)
|
|
||||||
error("error decompressed packet size exceeds max\n");
|
|
||||||
if (mppc_expand(s->p, length, ctype, &roff, &rlen) == -1)
|
if (mppc_expand(s->p, length, ctype, &roff, &rlen) == -1)
|
||||||
error("error while decompressing packet\n");
|
error("error while decompressing packet\n");
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user