From 5d495539196d4c9645f50fbb8f685b33ea5c5820 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Tue, 10 Jun 2014 16:25:54 -0700 Subject: [PATCH] work on 32 bit planar bitmap compressor --- libxrdp/xrdp_bitmap32_compress.c | 61 +++++++++++++++++++++++- xrdp/xrdp_bitmap.c | 79 ++++++++++++++++++++++++++++++-- 2 files changed, 134 insertions(+), 6 deletions(-) diff --git a/libxrdp/xrdp_bitmap32_compress.c b/libxrdp/xrdp_bitmap32_compress.c index b681d040..b1aaaa9a 100644 --- a/libxrdp/xrdp_bitmap32_compress.c +++ b/libxrdp/xrdp_bitmap32_compress.c @@ -19,14 +19,73 @@ * 32 bpp compression */ +/* +RDP 6.0 Bitmap Compression +http://msdn.microsoft.com/en-us/library/cc241877.aspx +*/ + #include "libxrdp.h" /*****************************************************************************/ +/* returns the number of lines compressed */ int APP_CC xrdp_bitmap32_compress(char *in_data, int width, int height, struct stream *s, int bpp, int byte_limit, int start_line, struct stream *temp_s, int e) { - return 0; + int pixel; + int *ptr32; + char *ptr8; + char *alpha_data; + char *red_data; + char *green_data; + char *blue_data; + int alpha_bytes; + int red_bytes; + int green_bytes; + int blue_bytes; + int iindex; + int jindex; + int cx; + int cy; + + alpha_data = g_malloc(width * height * 4, 0); + red_data = alpha_data + width * height; + green_data = red_data + width * height; + blue_data = green_data + width * height; + alpha_bytes = 0; + red_bytes = 0; + green_bytes = 0; + blue_bytes = 0; + cx = width; + cy = 0; + + /* split planes */ + while (start_line >= 0) + { + ptr32 = (int *) (in_data + start_line * width * 4); + for (iindex = 0; iindex < width; iindex++) + { + pixel = *ptr32; + ptr32++; + alpha_data[alpha_bytes] = pixel >> 24; + alpha_bytes++; + red_data[red_bytes] = pixel >> 16; + red_bytes++; + green_data[green_bytes] = pixel >> 8; + green_bytes++; + blue_data[blue_bytes] = pixel >> 0; + blue_bytes++; + } + start_line--; + cy++; + } + out_uint8(s, 0x20); /* no alpha */ + out_uint8a(s, red_data, red_bytes); + out_uint8a(s, green_data, green_bytes); + out_uint8a(s, blue_data, blue_bytes); + out_uint8(s, 0x00); + g_free(alpha_data); + return cy; } diff --git a/xrdp/xrdp_bitmap.c b/xrdp/xrdp_bitmap.c index 49750221..87fb0ebc 100644 --- a/xrdp/xrdp_bitmap.c +++ b/xrdp/xrdp_bitmap.c @@ -679,7 +679,7 @@ xrdp_bitmap_get_pixel(struct xrdp_bitmap *self, int x, int y) { return GETPIXEL16(self->data, x, y, self->width); } - else if (self->bpp == 24) + else if (self->bpp >= 24) { return GETPIXEL32(self->data, x, y, self->width); } @@ -712,7 +712,7 @@ xrdp_bitmap_set_pixel(struct xrdp_bitmap *self, int x, int y, int pixel) { SETPIXEL16(self->data, x, y, self->width, pixel); } - else if (self->bpp == 24) + else if (self->bpp >= 24) { SETPIXEL32(self->data, x, y, self->width, pixel); } @@ -779,7 +779,7 @@ xrdp_bitmap_copy_box(struct xrdp_bitmap *self, return 1; } - if (self->bpp == 24) + if (self->bpp >= 24) { s32 = ((tui32 *)(self->data)) + (self->width * y + x); d32 = ((tui32 *)(dest->data)) + (dest->width * desty + destx); @@ -849,7 +849,7 @@ xrdp_bitmap_hash_crc(struct xrdp_bitmap *self) int index; char hash_data[16]; - if (self->bpp == 24) + if (self->bpp >= 24) { bytes = self->width * self->height * 4; } @@ -953,7 +953,76 @@ xrdp_bitmap_copy_box_with_crc(struct xrdp_bitmap *self, CRC_PASS(self->height, crc); CRC_PASS(self->height >> 8, crc); - if (self->bpp == 24) + if (self->bpp == 32) + { + s32 = ((tui32 *)(self->data)) + (self->width * y + x); + d32 = ((tui32 *)(dest->data)) + (dest->width * desty + destx); + incs = self->width - cx; + incd = dest->width - cx; + + for (i = 0; i < cy; i++) + { + j = 0; + + while (j < cx - 4) + { + pixel = *s32; + *d32 = pixel; + CRC_PASS(pixel, crc); + CRC_PASS(pixel >> 8, crc); + CRC_PASS(pixel >> 16, crc); + CRC_PASS(pixel >> 24, crc); + s32++; + d32++; + + pixel = *s32; + *d32 = pixel; + CRC_PASS(pixel, crc); + CRC_PASS(pixel >> 8, crc); + CRC_PASS(pixel >> 16, crc); + CRC_PASS(pixel >> 24, crc); + s32++; + d32++; + + pixel = *s32; + *d32 = pixel; + CRC_PASS(pixel, crc); + CRC_PASS(pixel >> 8, crc); + CRC_PASS(pixel >> 16, crc); + CRC_PASS(pixel >> 24, crc); + s32++; + d32++; + + pixel = *s32; + *d32 = pixel; + CRC_PASS(pixel, crc); + CRC_PASS(pixel >> 8, crc); + CRC_PASS(pixel >> 16, crc); + CRC_PASS(pixel >> 24, crc); + s32++; + d32++; + + j += 4; + } + while (j < cx) + { + pixel = *s32; + *d32 = pixel; + CRC_PASS(pixel, crc); + CRC_PASS(pixel >> 8, crc); + CRC_PASS(pixel >> 16, crc); + CRC_PASS(pixel >> 24, crc); + s32++; + d32++; + + j += 1; + } + + s32 += incs; + d32 += incd; + } + } + else if (self->bpp == 24) { s32 = ((tui32 *)(self->data)) + (self->width * y + x); d32 = ((tui32 *)(dest->data)) + (dest->width * desty + destx);