libfreerdp-codec: refactor planar decompression

This commit is contained in:
Marc-André Moreau 2013-11-29 03:06:39 -05:00
parent d9e1c0abaa
commit 82b12621af

View File

@ -28,124 +28,121 @@
#include "planar.h" #include "planar.h"
#define IN_UINT8_MV(_p) (*((_p)++)) static int freerdp_bitmap_planar_decompress_plane_rle(BYTE* inPlane, int width, int height, BYTE* outPlane, int size)
static int freerdp_bitmap_planar_decompress_plane_rle(BYTE* in, int width, int height, BYTE* out, int size)
{ {
int indexw; int x, y;
int indexh; BYTE* srcp;
int code; BYTE* dstp;
int collen; UINT32 pixel;
int replen; int scanline;
int color; int cRawBytes;
int x; int nRunLength;
int revcode; int deltaValue;
BYTE* last_line; BYTE controlByte;
BYTE* this_line; BYTE* currentScanline;
BYTE* org_in; BYTE* previousScanline;
BYTE* org_out;
org_in = in; srcp = inPlane;
org_out = out; dstp = outPlane;
last_line = 0; scanline = width * 4;
indexh = 0; previousScanline = NULL;
while (indexh < height) y = 0;
while (y < height)
{ {
out = (org_out + width * height * 4) - ((indexh + 1) * width * 4); pixel = 0;
color = 0; dstp = (outPlane + height * scanline) - ((y + 1) * scanline);
this_line = out; currentScanline = dstp;
indexw = 0;
if (last_line == 0) x = 0;
while (x < width)
{ {
while (indexw < width) controlByte = *srcp;
srcp++;
nRunLength = PLANAR_CONTROL_BYTE_RUN_LENGTH(controlByte);
cRawBytes = PLANAR_CONTROL_BYTE_RAW_BYTES(controlByte);
if (nRunLength == 1)
{ {
code = IN_UINT8_MV(in); nRunLength = cRawBytes + 16;
cRawBytes = 0;
}
else if (nRunLength == 2)
{
nRunLength = cRawBytes + 32;
cRawBytes = 0;
}
replen = code & 0xf; if (!previousScanline)
collen = (code >> 4) & 0xf; {
revcode = (replen << 4) | collen; /* first scanline, absolute values */
if ((revcode <= 47) && (revcode >= 16)) while (cRawBytes > 0)
{ {
replen = revcode; pixel = *srcp;
collen = 0; srcp++;
*dstp = pixel;
dstp += 4;
x++;
cRawBytes--;
} }
while (collen > 0) while (nRunLength > 0)
{ {
color = IN_UINT8_MV(in); *dstp = pixel;
*out = color; dstp += 4;
out += 4; x++;
indexw++; nRunLength--;
collen--;
}
while (replen > 0)
{
*out = color;
out += 4;
indexw++;
replen--;
} }
} }
} else
else
{
while (indexw < width)
{ {
code = IN_UINT8_MV(in); /* delta values relative to previous scanline */
replen = code & 0xf; while (cRawBytes > 0)
collen = (code >> 4) & 0xf;
revcode = (replen << 4) | collen;
if ((revcode <= 47) && (revcode >= 16))
{ {
replen = revcode; deltaValue = *srcp;
collen = 0; srcp++;
}
while (collen > 0) if (deltaValue & 1)
{
x = IN_UINT8_MV(in);
if (x & 1)
{ {
x = x >> 1; deltaValue = deltaValue >> 1;
x = x + 1; deltaValue = deltaValue + 1;
color = -x; pixel = -deltaValue;
} }
else else
{ {
x = x >> 1; deltaValue = deltaValue >> 1;
color = x; pixel = deltaValue;
} }
x = last_line[indexw * 4] + color; deltaValue = previousScanline[x * 4] + pixel;
*out = x; *dstp = deltaValue;
out += 4; dstp += 4;
indexw++; x++;
collen--; cRawBytes--;
} }
while (replen > 0) while (nRunLength > 0)
{ {
x = last_line[indexw * 4] + color; deltaValue = previousScanline[x * 4] + pixel;
*out = x; *dstp = deltaValue;
out += 4; dstp += 4;
indexw++; x++;
replen--; nRunLength--;
} }
} }
} }
indexh++; previousScanline = currentScanline;
last_line = this_line; y++;
} }
return (int) (in - org_in); return (int) (srcp - inPlane);
} }
static int freerdp_bitmap_planar_decompress_plane_raw(BYTE* srcData, int width, int height, BYTE* dstData, int size) static int freerdp_bitmap_planar_decompress_plane_raw(BYTE* srcData, int width, int height, BYTE* dstData, int size)
@ -166,62 +163,53 @@ static int freerdp_bitmap_planar_decompress_plane_raw(BYTE* srcData, int width,
int freerdp_bitmap_planar_decompress(BYTE* srcData, BYTE* dstData, int width, int height, int size) int freerdp_bitmap_planar_decompress(BYTE* srcData, BYTE* dstData, int width, int height, int size)
{ {
BYTE* srcp; BYTE* srcp;
int dstSize;
BYTE FormatHeader; BYTE FormatHeader;
int bytesProcessed;
int totalProcessed;
srcp = srcData; srcp = srcData;
FormatHeader = *srcp; FormatHeader = *srcp;
totalProcessed = 1;
srcp++; srcp++;
if (!(FormatHeader & PLANAR_FORMAT_HEADER_NA)) if (!(FormatHeader & PLANAR_FORMAT_HEADER_NA))
{ {
if (FormatHeader & PLANAR_FORMAT_HEADER_RLE) if (FormatHeader & PLANAR_FORMAT_HEADER_RLE)
{ {
bytesProcessed = freerdp_bitmap_planar_decompress_plane_rle(srcp, width, height, dstData + 3, size - totalProcessed); dstSize = freerdp_bitmap_planar_decompress_plane_rle(srcp, width, height, dstData + 3, size - (srcp - srcData));
totalProcessed += bytesProcessed; srcp += dstSize;
srcp += bytesProcessed;
} }
else else
{ {
bytesProcessed = freerdp_bitmap_planar_decompress_plane_raw(srcp, width, height, dstData + 3, size - totalProcessed); dstSize = freerdp_bitmap_planar_decompress_plane_raw(srcp, width, height, dstData + 3, size - (srcp - srcData));
totalProcessed += bytesProcessed; srcp += dstSize;
srcp += bytesProcessed;
} }
} }
if (FormatHeader & PLANAR_FORMAT_HEADER_RLE) if (FormatHeader & PLANAR_FORMAT_HEADER_RLE)
{ {
bytesProcessed = freerdp_bitmap_planar_decompress_plane_rle(srcp, width, height, dstData + 2, size - totalProcessed); dstSize = freerdp_bitmap_planar_decompress_plane_rle(srcp, width, height, dstData + 2, size - (srcp - srcData));
totalProcessed += bytesProcessed; srcp += dstSize;
srcp += bytesProcessed;
bytesProcessed = freerdp_bitmap_planar_decompress_plane_rle(srcp, width, height, dstData + 1, size - totalProcessed); dstSize = freerdp_bitmap_planar_decompress_plane_rle(srcp, width, height, dstData + 1, size - (srcp - srcData));
totalProcessed += bytesProcessed; srcp += dstSize;
srcp += bytesProcessed;
bytesProcessed = freerdp_bitmap_planar_decompress_plane_rle(srcp, width, height, dstData + 0, size - totalProcessed); dstSize = freerdp_bitmap_planar_decompress_plane_rle(srcp, width, height, dstData + 0, size - (srcp - srcData));
totalProcessed += bytesProcessed; srcp += dstSize;
srcp += bytesProcessed;
} }
else else
{ {
bytesProcessed = freerdp_bitmap_planar_decompress_plane_raw(srcp, width, height, dstData + 2, size - totalProcessed); dstSize = freerdp_bitmap_planar_decompress_plane_raw(srcp, width, height, dstData + 2, size - (srcp - srcData));
totalProcessed += bytesProcessed; srcp += dstSize;
srcp += bytesProcessed;
bytesProcessed = freerdp_bitmap_planar_decompress_plane_raw(srcp, width, height, dstData + 1, size - totalProcessed); dstSize = freerdp_bitmap_planar_decompress_plane_raw(srcp, width, height, dstData + 1, size - (srcp - srcData));
totalProcessed += bytesProcessed; srcp += dstSize;
srcp += bytesProcessed;
bytesProcessed = freerdp_bitmap_planar_decompress_plane_raw(srcp, width, height, dstData + 0, size - totalProcessed); dstSize = freerdp_bitmap_planar_decompress_plane_raw(srcp, width, height, dstData + 0, size - (srcp - srcData));
totalProcessed += bytesProcessed + 1; srcp += dstSize;
srcp += bytesProcessed; srcp++;
} }
return (size == totalProcessed) ? 1 : 0; return (size == (srcp - srcData)) ? 1 : 0;
} }
int freerdp_split_color_planes(BYTE* data, UINT32 format, int width, int height, int scanline, BYTE* planes[5]) int freerdp_split_color_planes(BYTE* data, UINT32 format, int width, int height, int scanline, BYTE* planes[5])