added 32 bpp color decompression

This commit is contained in:
Jay Sorg 2011-07-09 19:55:11 -07:00
parent dfc6cc3a06
commit 19223a2503
3 changed files with 232 additions and 51 deletions

View File

@ -47,7 +47,7 @@ set(LIBFREERDP_CORE_SRCS
tpkt.h
transport.c
transport.h
rle_bitmap_stream.c
bitmap.c
)
include_directories(../libfreerdp-asn1)

View File

@ -1,6 +1,6 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* RLE Compressed Bitmap Stream
* Compressed Bitmap
*
* Copyright 2011 Jay Sorg <jay.sorg@gmail.com>
*
@ -71,10 +71,10 @@ typedef uint32 PIXEL;
#define BLACK_PIXEL 0
#define WHITE_PIXEL 0xffffff
/*
Reads the supplied order header and extracts the compression
order code ID.
*/
/**
* Reads the supplied order header and extracts the compression
* order code ID.
*/
static uint32 ExtractCodeId(uint8 bOrderHdr)
{
int code;
@ -108,10 +108,10 @@ static uint32 ExtractCodeId(uint8 bOrderHdr)
return bOrderHdr >> 4;
}
/*
Extract the run length of a compression order.
*/
static uint32 ExtractRunLength(uint32 code, uint8 * pbOrderHdr, uint32 * advance)
/**
* Extract the run length of a compression order.
*/
static uint32 ExtractRunLength(uint32 code, uint8* pbOrderHdr, uint32* advance)
{
uint32 runLength;
uint32 ladvance;
@ -248,26 +248,207 @@ static uint32 ExtractRunLength(uint32 code, uint8 * pbOrderHdr, uint32 * advance
#define RLEEXTRA
#include "bitmap_inc.c"
int bitmap_decompress(void * inst, uint8 * output, int width, int height,
uint8 * input, int size, int Bpp)
#define IN_UINT8_MV(_p) (*((_p)++))
/**
* decompress a color plane
*/
static int process_plane(uint8* in, int width, int height, uint8* out, int size)
{
switch (Bpp)
int indexw;
int indexh;
int code;
int collen;
int replen;
int color;
int x;
int revcode;
uint8* last_line;
uint8* this_line;
uint8* org_in;
uint8* org_out;
org_in = in;
org_out = out;
last_line = 0;
indexh = 0;
while (indexh < height)
{
case 1:
RleDecompress8to8(input, size, output, width, width, height);
break;
case 2:
RleDecompress16to16(input, size, output, width * 2, width, height);
break;
case 3:
RleDecompress24to24(input, size, output, width * 3, width, height);
break;
case 4:
/* TODO */
break;
default:
/* TODO */
break;
out = (org_out + width * height * 4) - ((indexh + 1) * width * 4);
color = 0;
this_line = out;
indexw = 0;
if (last_line == 0)
{
while (indexw < width)
{
code = IN_UINT8_MV(in);
replen = code & 0xf;
collen = (code >> 4) & 0xf;
revcode = (replen << 4) | collen;
if ((revcode <= 47) && (revcode >= 16))
{
replen = revcode;
collen = 0;
}
while (collen > 0)
{
color = IN_UINT8_MV(in);
*out = color;
out += 4;
indexw++;
collen--;
}
while (replen > 0)
{
*out = color;
out += 4;
indexw++;
replen--;
}
}
}
else
{
while (indexw < width)
{
code = IN_UINT8_MV(in);
replen = code & 0xf;
collen = (code >> 4) & 0xf;
revcode = (replen << 4) | collen;
if ((revcode <= 47) && (revcode >= 16))
{
replen = revcode;
collen = 0;
}
while (collen > 0)
{
x = IN_UINT8_MV(in);
if (x & 1)
{
x = x >> 1;
x = x + 1;
color = -x;
}
else
{
x = x >> 1;
color = x;
}
x = last_line[indexw * 4] + color;
*out = x;
out += 4;
indexw++;
collen--;
}
while (replen > 0)
{
x = last_line[indexw * 4] + color;
*out = x;
out += 4;
indexw++;
replen--;
}
}
}
indexh++;
last_line = this_line;
}
return (int) (in - org_in);
}
/**
* 4 byte bitmap decompress
*/
static int bitmap_decompress4(uint8* output, int width, int height, uint8* input, int size)
{
int code;
int bytes_pro;
int total_pro;
code = IN_UINT8_MV(input);
if (code != 0x10)
{
return False;
}
total_pro = 1;
bytes_pro = process_plane(input, width, height, output + 3, size - total_pro);
total_pro += bytes_pro;
input += bytes_pro;
bytes_pro = process_plane(input, width, height, output + 2, size - total_pro);
total_pro += bytes_pro;
input += bytes_pro;
bytes_pro = process_plane(input, width, height, output + 1, size - total_pro);
total_pro += bytes_pro;
input += bytes_pro;
bytes_pro = process_plane(input, width, height, output + 0, size - total_pro);
total_pro += bytes_pro;
return size == total_pro;
}
/**
* bitmap flip
*/
static int bitmap_flip(uint8* src, uint8* dst, int delta, int height)
{
int index;
dst = (dst + delta * height) - delta;
for (index = 0; index < height; index++)
{
memcpy(dst, src, delta);
src += delta;
dst -= delta;
}
return 0;
}
/**
* bitmap decompression routine
*/
int bitmap_decompress(void* inst, uint8* output, int width, int height,
uint8* input, int size, int in_bpp, int out_bpp)
{
uint8* data;
if (in_bpp == 16 && out_bpp == 16)
{
data = (uint8*)xmalloc(width * height * 2);
RleDecompress16to16(input, size, data, width * 2, width, height);
bitmap_flip(data, output, width * 2, height);
xfree(data);
}
else if (in_bpp == 32 && out_bpp == 32)
{
if (!bitmap_decompress4(output, width, height, input, size))
{
return 1;
}
}
else if (in_bpp == 15 && out_bpp == 15)
{
data = (uint8*)xmalloc(width * height * 2);
RleDecompress16to16(input, size, output, width * 2, width, height);
bitmap_flip(data, output, width * 2, height);
xfree(data);
}
else if (in_bpp == 8 && out_bpp == 8)
{
data = (uint8*)xmalloc(width * height);
RleDecompress8to8(input, size, output, width, width, height);
bitmap_flip(data, output, width, height);
xfree(data);
}
else if (in_bpp == 24 && out_bpp == 24)
{
data = (uint8*)xmalloc(width * height * 3);
RleDecompress24to24(input, size, output, width * 3, width, height);
bitmap_flip(data, output, width * 3, height);
xfree(data);
}
else
{
return 1;
}
return 0;
}

View File

@ -19,10 +19,10 @@
/* do not compile the file directly */
/*
Write a foreground/background image to a destination buffer.
*/
static uint8 * WRITEFGBGIMAGE(uint8 * pbDest, uint32 rowDelta,
/**
* Write a foreground/background image to a destination buffer.
*/
static uint8* WRITEFGBGIMAGE(uint8* pbDest, uint32 rowDelta,
uint8 bitmask, PIXEL fgPel, uint32 cBits)
{
PIXEL xorPixel;
@ -138,11 +138,11 @@ static uint8 * WRITEFGBGIMAGE(uint8 * pbDest, uint32 rowDelta,
return pbDest;
}
/*
Write a foreground/background image to a destination buffer
for the first line of compressed data.
*/
static uint8 * WRITEFIRSTLINEFGBGIMAGE(uint8 * pbDest, uint8 bitmask,
/**
* Write a foreground/background image to a destination buffer
* for the first line of compressed data.
*/
static uint8* WRITEFIRSTLINEFGBGIMAGE(uint8* pbDest, uint8 bitmask,
PIXEL fgPel, uint32 cBits)
{
if (bitmask & g_MaskBit0)
@ -248,15 +248,15 @@ static uint8 * WRITEFIRSTLINEFGBGIMAGE(uint8 * pbDest, uint8 bitmask,
return pbDest;
}
/*
Decompress an RLE compressed bitmap.
*/
void RLEDECOMPRESS(uint8 * pbSrcBuffer, uint32 cbSrcBuffer, uint8 * pbDestBuffer,
/**
* Decompress an RLE compressed bitmap.
*/
void RLEDECOMPRESS(uint8* pbSrcBuffer, uint32 cbSrcBuffer, uint8* pbDestBuffer,
uint32 rowDelta, uint32 width, uint32 height)
{
uint8 * pbSrc = pbSrcBuffer;
uint8 * pbEnd = pbSrcBuffer + cbSrcBuffer;
uint8 * pbDest = pbDestBuffer;
uint8* pbSrc = pbSrcBuffer;
uint8* pbEnd = pbSrcBuffer + cbSrcBuffer;
uint8* pbDest = pbDestBuffer;
PIXEL temp;
PIXEL fgPel = WHITE_PIXEL;
@ -304,7 +304,7 @@ void RLEDECOMPRESS(uint8 * pbSrcBuffer, uint32 cbSrcBuffer, uint8 * pbDestBuffer
DESTNEXTPIXEL(pbDest);
runLength = runLength - 1;
}
while (runLength > UNROLL_COUNT)
while (runLength >= UNROLL_COUNT)
{
UNROLL(
DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
@ -327,7 +327,7 @@ void RLEDECOMPRESS(uint8 * pbSrcBuffer, uint32 cbSrcBuffer, uint8 * pbDestBuffer
DESTNEXTPIXEL(pbDest);
runLength = runLength - 1;
}
while (runLength > UNROLL_COUNT)
while (runLength >= UNROLL_COUNT)
{
UNROLL(
DESTREADPIXEL(temp, pbDest - rowDelta);
@ -368,7 +368,7 @@ void RLEDECOMPRESS(uint8 * pbSrcBuffer, uint32 cbSrcBuffer, uint8 * pbDestBuffer
}
if (fFirstLine)
{
while (runLength > UNROLL_COUNT)
while (runLength >= UNROLL_COUNT)
{
UNROLL(
DESTWRITEPIXEL(pbDest, fgPel);
@ -384,7 +384,7 @@ void RLEDECOMPRESS(uint8 * pbSrcBuffer, uint32 cbSrcBuffer, uint8 * pbDestBuffer
}
else
{
while (runLength > UNROLL_COUNT)
while (runLength >= UNROLL_COUNT)
{
UNROLL(
DESTREADPIXEL(temp, pbDest - rowDelta);
@ -411,7 +411,7 @@ void RLEDECOMPRESS(uint8 * pbSrcBuffer, uint32 cbSrcBuffer, uint8 * pbDestBuffer
SRCNEXTPIXEL(pbSrc);
SRCREADPIXEL(pixelB, pbSrc);
SRCNEXTPIXEL(pbSrc);
while (runLength > UNROLL_COUNT)
while (runLength >= UNROLL_COUNT)
{
UNROLL(
DESTWRITEPIXEL(pbDest, pixelA);
@ -437,7 +437,7 @@ void RLEDECOMPRESS(uint8 * pbSrcBuffer, uint32 cbSrcBuffer, uint8 * pbDestBuffer
pbSrc = pbSrc + advance;
SRCREADPIXEL(pixelA, pbSrc);
SRCNEXTPIXEL(pbSrc);
while (runLength > UNROLL_COUNT)
while (runLength >= UNROLL_COUNT)
{
UNROLL(
DESTWRITEPIXEL(pbDest, pixelA);
@ -504,7 +504,7 @@ void RLEDECOMPRESS(uint8 * pbSrcBuffer, uint32 cbSrcBuffer, uint8 * pbDestBuffer
case MEGA_MEGA_COLOR_IMAGE:
runLength = ExtractRunLength(code, pbSrc, &advance);
pbSrc = pbSrc + advance;
while (runLength > UNROLL_COUNT)
while (runLength >= UNROLL_COUNT)
{
UNROLL(
SRCREADPIXEL(temp, pbSrc);