libfreerdp-core: start using jay's bitmap decompressor

This commit is contained in:
Marc-André Moreau 2011-07-25 14:50:26 -04:00
parent 0d936404a9
commit 653d0441aa
6 changed files with 149 additions and 97 deletions

View File

@ -1170,8 +1170,8 @@ void test_bitmap(void)
bpp = 8;
comp_size = sizeof(compressed_16x1x8);
decomp_size = sizeof(decompressed_16x1x8);
CU_ASSERT(bitmap_decompress(0, t->decompressed_16x1x8, width, height,
compressed_16x1x8, comp_size, bpp, bpp) == 0);
CU_ASSERT(bitmap_decompress(compressed_16x1x8, t->decompressed_16x1x8,
width, height, comp_size, bpp, bpp) == True);
CU_ASSERT(memcmp(t->decompressed_16x1x8, decompressed_16x1x8,
decomp_size) == 0);
@ -1180,8 +1180,8 @@ void test_bitmap(void)
bpp = 8;
comp_size = sizeof(compressed_32x32x8);
decomp_size = sizeof(decompressed_32x32x8);
CU_ASSERT(bitmap_decompress(0, t->decompressed_32x32x8, width, height,
compressed_32x32x8, comp_size, bpp, bpp) == 0);
CU_ASSERT(bitmap_decompress(compressed_32x32x8, t->decompressed_32x32x8,
width, height, comp_size, bpp, bpp) == True);
CU_ASSERT(memcmp(t->decompressed_32x32x8, decompressed_32x32x8,
decomp_size) == 0);
@ -1190,8 +1190,8 @@ void test_bitmap(void)
bpp = 16;
comp_size = sizeof(compressed_16x1x16);
decomp_size = sizeof(decompressed_16x1x16);
CU_ASSERT(bitmap_decompress(0, t->decompressed_16x1x16, width, height,
compressed_16x1x16, comp_size, bpp, bpp) == 0);
CU_ASSERT(bitmap_decompress(compressed_16x1x16, t->decompressed_16x1x16,
width, height, comp_size, bpp, bpp) == True);
CU_ASSERT(memcmp(t->decompressed_16x1x16, decompressed_16x1x16,
decomp_size) == 0);
@ -1200,8 +1200,8 @@ void test_bitmap(void)
bpp = 16;
comp_size = sizeof(compressed_32x32x16);
decomp_size = sizeof(decompressed_32x32x16);
CU_ASSERT(bitmap_decompress(0, t->decompressed_32x32x16, width, height,
compressed_32x32x16, comp_size, bpp, bpp) == 0);
CU_ASSERT(bitmap_decompress(compressed_32x32x16, t->decompressed_32x32x16,
width, height, comp_size, bpp, bpp) == True);
CU_ASSERT(memcmp(t->decompressed_32x32x16, decompressed_32x32x16,
decomp_size) == 0);
@ -1210,8 +1210,8 @@ void test_bitmap(void)
bpp = 24;
comp_size = sizeof(compressed_16x1x24);
decomp_size = sizeof(decompressed_16x1x24);
CU_ASSERT(bitmap_decompress(0, t->decompressed_16x1x24, width, height,
compressed_16x1x24, comp_size, bpp, bpp) == 0);
CU_ASSERT(bitmap_decompress(compressed_16x1x24, t->decompressed_16x1x24,
width, height, comp_size, bpp, bpp) == True);
CU_ASSERT(memcmp(t->decompressed_16x1x24, decompressed_16x1x24,
decomp_size) == 0);
@ -1220,8 +1220,8 @@ void test_bitmap(void)
bpp = 24;
comp_size = sizeof(compressed_32x32x24);
decomp_size = sizeof(decompressed_32x32x24);
CU_ASSERT(bitmap_decompress(0, t->decompressed_32x32x24, width, height,
compressed_32x32x24, comp_size, bpp, bpp) == 0);
CU_ASSERT(bitmap_decompress(compressed_32x32x24, t->decompressed_32x32x24,
width, height, comp_size, bpp, bpp) == True);
CU_ASSERT(memcmp(t->decompressed_32x32x24, decompressed_32x32x24,
decomp_size) == 0);
@ -1230,8 +1230,8 @@ void test_bitmap(void)
bpp = 32;
comp_size = sizeof(compressed_16x1x32);
decomp_size = sizeof(decompressed_16x1x32);
CU_ASSERT(bitmap_decompress(0, t->decompressed_16x1x32, width, height,
compressed_16x1x32, comp_size, bpp, bpp) == 0);
CU_ASSERT(bitmap_decompress(compressed_16x1x32, t->decompressed_16x1x32,
width, height, comp_size, bpp, bpp) == True);
CU_ASSERT(memcmp(t->decompressed_16x1x32, decompressed_16x1x32,
decomp_size) == 0);
@ -1240,8 +1240,8 @@ void test_bitmap(void)
bpp = 32;
comp_size = sizeof(compressed_32x32x32);
decomp_size = sizeof(decompressed_32x32x32);
CU_ASSERT(bitmap_decompress(0, t->decompressed_32x32x32, width, height,
compressed_32x32x32, comp_size, bpp, bpp) == 0);
CU_ASSERT(bitmap_decompress(compressed_32x32x32, t->decompressed_32x32x32,
width, height, comp_size, bpp, bpp) == True);
CU_ASSERT(memcmp(t->decompressed_32x32x32, decompressed_32x32x32,
decomp_size) == 0);

View File

@ -22,6 +22,8 @@ add_definitions(-DEXT_PATH="/usr/lib/freerdp/extensions")
set(LIBFREERDP_CORE_SRCS
activation.c
activation.h
bitmap.c
bitmap.h
ber.c
ber.h
gcc.c
@ -71,7 +73,6 @@ set(LIBFREERDP_CORE_SRCS
transport.h
update.c
update.h
bitmap.c
)
add_library(freerdp-core SHARED ${LIBFREERDP_CORE_SRCS})

View File

@ -17,6 +17,8 @@
* limitations under the License.
*/
#include "bitmap.h"
/*
RLE Compressed Bitmap Stream (RLE_BITMAP_STREAM)
http://msdn.microsoft.com/en-us/library/cc240895%28v=prot.10%29.aspx
@ -24,30 +26,6 @@
http://msdn.microsoft.com/en-us/library/dd240593%28v=prot.10%29.aspx
*/
#include <freerdp/utils/stream.h>
#include <freerdp/utils/memory.h>
#define REGULAR_BG_RUN 0x0
#define MEGA_MEGA_BG_RUN 0xF0
#define REGULAR_FG_RUN 0x1
#define MEGA_MEGA_FG_RUN 0xF1
#define LITE_SET_FG_FG_RUN 0xC
#define MEGA_MEGA_SET_FG_RUN 0xF6
#define LITE_DITHERED_RUN 0xE
#define MEGA_MEGA_DITHERED_RUN 0xF8
#define REGULAR_COLOR_RUN 0x3
#define MEGA_MEGA_COLOR_RUN 0xF3
#define REGULAR_FGBG_IMAGE 0x2
#define MEGA_MEGA_FGBG_IMAGE 0xF2
#define LITE_SET_FG_FGBG_IMAGE 0xD
#define MEGA_MEGA_SET_FGBG_IMAGE 0xF7
#define REGULAR_COLOR_IMAGE 0x4
#define MEGA_MEGA_COLOR_IMAGE 0xF4
#define SPECIAL_FGBG_1 0xF9
#define SPECIAL_FGBG_2 0xFA
#define SPECIAL_WHITE 0xFD
#define SPECIAL_BLACK 0xFE
/*
Bitmasks
*/
@ -66,11 +44,6 @@ static uint8 g_MaskLiteRunLength = 0x0F;
static uint8 g_MaskSpecialFgBg1 = 0x03;
static uint8 g_MaskSpecialFgBg2 = 0x05;
typedef uint32 PIXEL;
#define BLACK_PIXEL 0
#define WHITE_PIXEL 0xffffff
/**
* Reads the supplied order header and extracts the compression
* order code ID.
@ -360,30 +333,31 @@ static int process_plane(uint8* in, int width, int height, uint8* out, int size)
/**
* 4 byte bitmap decompress
*/
static int bitmap_decompress4(uint8* output, int width, int height, uint8* input, int size)
static boolean bitmap_decompress4(uint8* srcData, uint8* dstData, int width, int height, int size)
{
int code;
int bytes_pro;
int total_pro;
code = IN_UINT8_MV(input);
code = IN_UINT8_MV(srcData);
if (code != 0x10)
{
return False;
}
total_pro = 1;
bytes_pro = process_plane(input, width, height, output + 3, size - total_pro);
bytes_pro = process_plane(srcData, width, height, dstData + 3, size - total_pro);
total_pro += bytes_pro;
input += bytes_pro;
bytes_pro = process_plane(input, width, height, output + 2, size - total_pro);
srcData += bytes_pro;
bytes_pro = process_plane(srcData, width, height, dstData + 2, size - total_pro);
total_pro += bytes_pro;
input += bytes_pro;
bytes_pro = process_plane(input, width, height, output + 1, size - total_pro);
srcData += bytes_pro;
bytes_pro = process_plane(srcData, width, height, dstData + 1, size - total_pro);
total_pro += bytes_pro;
input += bytes_pro;
bytes_pro = process_plane(input, width, height, output + 0, size - total_pro);
srcData += bytes_pro;
bytes_pro = process_plane(srcData, width, height, dstData + 0, size - total_pro);
total_pro += bytes_pro;
return size == total_pro;
return (size == total_pro) ? True : False;
}
/**
@ -406,49 +380,47 @@ static int bitmap_flip(uint8* src, uint8* dst, int delta, int height)
/**
* bitmap decompression routine
*/
int bitmap_decompress(void* inst, uint8* output, int width, int height,
uint8* input, int size, int in_bpp, int out_bpp)
boolean bitmap_decompress(uint8* srcData, uint8* dstData, int width, int height, int size, int srcBpp, int dstBpp)
{
uint8* data;
if (in_bpp == 16 && out_bpp == 16)
if (srcBpp == 16 && dstBpp == 16)
{
data = (uint8*)xmalloc(width * height * 2);
RleDecompress16to16(input, size, data, width * 2, width, height);
bitmap_flip(data, output, width * 2, height);
data = (uint8*) xmalloc(width * height * 2);
RleDecompress16to16(srcData, size, data, width * 2, width, height);
bitmap_flip(data, dstData, width * 2, height);
xfree(data);
}
else if (in_bpp == 32 && out_bpp == 32)
else if (srcBpp == 32 && dstBpp == 32)
{
if (!bitmap_decompress4(output, width, height, input, size))
{
return 1;
}
if (bitmap_decompress4(srcData, dstData, width, height, size) != True)
return False;
}
else if (in_bpp == 15 && out_bpp == 15)
else if (srcBpp == 15 && dstBpp == 15)
{
data = (uint8*)xmalloc(width * height * 2);
RleDecompress16to16(input, size, data, width * 2, width, height);
bitmap_flip(data, output, width * 2, height);
data = (uint8*) xmalloc(width * height * 2);
RleDecompress16to16(srcData, size, data, width * 2, width, height);
bitmap_flip(data, dstData, width * 2, height);
xfree(data);
}
else if (in_bpp == 8 && out_bpp == 8)
else if (srcBpp == 8 && dstBpp == 8)
{
data = (uint8*)xmalloc(width * height);
RleDecompress8to8(input, size, data, width, width, height);
bitmap_flip(data, output, width, height);
data = (uint8*) xmalloc(width * height);
RleDecompress8to8(srcData, size, data, width, width, height);
bitmap_flip(data, dstData, width, height);
xfree(data);
}
else if (in_bpp == 24 && out_bpp == 24)
else if (srcBpp == 24 && dstBpp == 24)
{
data = (uint8*)xmalloc(width * height * 3);
RleDecompress24to24(input, size, data, width * 3, width, height);
bitmap_flip(data, output, width * 3, height);
data = (uint8*) xmalloc(width * height * 3);
RleDecompress24to24(srcData, size, data, width * 3, width, height);
bitmap_flip(data, dstData, width * 3, height);
xfree(data);
}
else
{
return 1;
return False;
}
return 0;
return True;
}

54
libfreerdp-core/bitmap.h Normal file
View File

@ -0,0 +1,54 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Compressed Bitmap
*
* Copyright 2011 Jay Sorg <jay.sorg@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __BITMAP_H
#define __BITMAP_H
#include <freerdp/utils/stream.h>
#include <freerdp/utils/memory.h>
#define REGULAR_BG_RUN 0x00
#define MEGA_MEGA_BG_RUN 0xF0
#define REGULAR_FG_RUN 0x01
#define MEGA_MEGA_FG_RUN 0xF1
#define LITE_SET_FG_FG_RUN 0x0C
#define MEGA_MEGA_SET_FG_RUN 0xF6
#define LITE_DITHERED_RUN 0x0E
#define MEGA_MEGA_DITHERED_RUN 0xF8
#define REGULAR_COLOR_RUN 0x03
#define MEGA_MEGA_COLOR_RUN 0xF3
#define REGULAR_FGBG_IMAGE 0x02
#define MEGA_MEGA_FGBG_IMAGE 0xF2
#define LITE_SET_FG_FGBG_IMAGE 0x0D
#define MEGA_MEGA_SET_FGBG_IMAGE 0xF7
#define REGULAR_COLOR_IMAGE 0x04
#define MEGA_MEGA_COLOR_IMAGE 0xF4
#define SPECIAL_FGBG_1 0xF9
#define SPECIAL_FGBG_2 0xFA
#define SPECIAL_WHITE 0xFD
#define SPECIAL_BLACK 0xFE
#define BLACK_PIXEL 0x000000
#define WHITE_PIXEL 0xFFFFFF
typedef uint32 PIXEL;
boolean bitmap_decompress(uint8* srcData, uint8* dstData, int width, int height, int size, int srcBpp, int dstBpp);
#endif /* __BITMAP_H */

View File

@ -263,15 +263,15 @@ void rdp_recv_order(rdpRdp* rdp, STREAM* s)
switch (controlFlags & ORDER_CLASS_MASK)
{
case ORDER_PRIMARY_CLASS:
rdp_recv_primary_order(rdp, s, controlFlags);
//rdp_recv_primary_order(rdp, s, controlFlags);
break;
case ORDER_SECONDARY_CLASS:
rdp_recv_secondary_order(rdp, s, controlFlags);
//rdp_recv_secondary_order(rdp, s, controlFlags);
break;
case ORDER_ALTSEC_CLASS:
rdp_recv_altsec_order(rdp, s, controlFlags);
//rdp_recv_altsec_order(rdp, s, controlFlags);
break;
}
}

View File

@ -34,12 +34,19 @@ void rdp_recv_orders_update(rdpRdp* rdp, STREAM* s)
stream_seek_uint16(s); /* pad2OctetsA (2 bytes) */
stream_read_uint16(s, numberOrders); /* numberOrders (2 bytes) */
stream_seek_uint16(s); /* pad2OctetsB (2 bytes) */
while (numberOrders > 0)
{
//rdp_recv_order(rdp, s);
numberOrders--;
}
}
void rdp_read_bitmap_data(STREAM* s, BITMAP_DATA* bitmap_data)
{
uint8* srcData;
uint16 dstSize;
boolean status;
uint16 bytesPerPixel;
stream_read_uint16(s, bitmap_data->left);
@ -51,19 +58,40 @@ void rdp_read_bitmap_data(STREAM* s, BITMAP_DATA* bitmap_data)
stream_read_uint16(s, bitmap_data->bpp);
stream_read_uint16(s, bitmap_data->flags);
stream_read_uint16(s, bitmap_data->length);
bytesPerPixel = (bitmap_data->bpp + 7) / 8;
if (bitmap_data->flags & BITMAP_COMPRESSION)
{
uint16 cbCompMainBodySize;
uint16 cbUncompressedSize;
stream_seek_uint16(s); /* cbCompFirstRowSize (2 bytes) */
stream_read_uint16(s, cbCompMainBodySize); /* cbCompMainBodySize (2 bytes) */
stream_seek_uint16(s); /* cbScanWidth (2 bytes) */
stream_read_uint16(s, cbUncompressedSize); /* cbUncompressedSize (2 bytes) */
dstSize = cbUncompressedSize;
bitmap_data->length = cbCompMainBodySize;
}
else
{
dstSize = bitmap_data->width * bitmap_data->height * bytesPerPixel;
}
stream_get_mark(s, srcData);
stream_seek(s, bitmap_data->length);
bytesPerPixel = (bitmap_data->bpp + 7) / 8;
dstSize = bitmap_data->width * bitmap_data->height * bytesPerPixel;
bitmap_data->data = (uint8*) xmalloc(dstSize);
if (bitmap_data->data != NULL)
bitmap_data->data = (uint8*) xrealloc(bitmap_data->data, dstSize);
else
bitmap_data->data = (uint8*) xmalloc(dstSize);
//printf("bytesPerPixel:%d, width:%d, height:%d dstSize:%d flags:0x%04X\n",
// bytesPerPixel, bitmap_data->width, bitmap_data->height, dstSize, bitmap_data->flags);
/*printf("width:%d height:%d bitsPerPixel:%d bytesPerPixel:%d dstSize:%d\n",
bitmap_data->width, bitmap_data->height, bitmap_data->bpp, bytesPerPixel, dstSize);*/
status = bitmap_decompress(srcData, bitmap_data->data, bitmap_data->width, bitmap_data->height,
bitmap_data->length, bitmap_data->bpp, bitmap_data->bpp);
if (status != True)
printf("bitmap decompression failed\n");
}
void rdp_recv_bitmap_update(rdpRdp* rdp, STREAM* s)
@ -80,9 +108,6 @@ void rdp_recv_bitmap_update(rdpRdp* rdp, STREAM* s)
rdp_read_bitmap_data(s, &bitmap_data);
numberRectangles--;
}
if (bitmap_data.data != NULL)
xfree(bitmap_data.data);
}
void rdp_recv_palette_update(rdpRdp* rdp, STREAM* s)