libfreerdp-codec: cleanup planar decoder

This commit is contained in:
Marc-André Moreau 2014-06-18 17:46:22 -04:00
parent 7818c77e5e
commit ea3822c357
3 changed files with 51 additions and 141 deletions

View File

@ -40,8 +40,6 @@ FREERDP_API int freerdp_bitmap_compress(char* in_data, int width, int height,
typedef struct _BITMAP_PLANAR_CONTEXT BITMAP_PLANAR_CONTEXT; typedef struct _BITMAP_PLANAR_CONTEXT BITMAP_PLANAR_CONTEXT;
FREERDP_API int freerdp_bitmap_planar_decompress(BYTE* srcData, BYTE* dstData, int width, int height, int size);
FREERDP_API BYTE* freerdp_bitmap_compress_planar(BITMAP_PLANAR_CONTEXT* context, BYTE* data, UINT32 format, FREERDP_API BYTE* freerdp_bitmap_compress_planar(BITMAP_PLANAR_CONTEXT* context, BYTE* data, UINT32 format,
int width, int height, int scanline, BYTE* dstData, int* dstSize); int width, int height, int scanline, BYTE* dstData, int* dstSize);

View File

@ -260,7 +260,9 @@ static UINT32 ExtractRunLength(UINT32 code, BYTE* pbOrderHdr, UINT32* advance)
*/ */
BOOL bitmap_decompress(BYTE* srcData, BYTE* dstData, int width, int height, int size, int srcBpp, int dstBpp) BOOL bitmap_decompress(BYTE* srcData, BYTE* dstData, int width, int height, int size, int srcBpp, int dstBpp)
{ {
BYTE* TmpBfr; int status;
BYTE* TmpBfr;
BYTE* pDstData;
if (srcBpp == 16 && dstBpp == 16) if (srcBpp == 16 && dstBpp == 16)
{ {
@ -271,7 +273,12 @@ BOOL bitmap_decompress(BYTE* srcData, BYTE* dstData, int width, int height, int
} }
else if (srcBpp == 32 && dstBpp == 32) else if (srcBpp == 32 && dstBpp == 32)
{ {
if (freerdp_bitmap_planar_decompress(srcData, dstData, width, height, size) < 0) pDstData = dstData;
status = planar_decompress(NULL, srcData, size, &pDstData,
PIXEL_FORMAT_XRGB32, width * 4, 0, 0, width, height);
if (status < 0)
return FALSE; return FALSE;
} }
else if (srcBpp == 15 && dstBpp == 15) else if (srcBpp == 15 && dstBpp == 15)

View File

@ -28,7 +28,7 @@
#include "planar.h" #include "planar.h"
static int freerdp_bitmap_planar_decompress_plane_rle(BYTE* inPlane, int width, int height, BYTE* outPlane, int srcSize) static int planar_decompress_plane_rle(BYTE* pSrcData, UINT32 SrcSize, BYTE* pDstData, int nWidth, int nHeight, int nChannel)
{ {
int k; int k;
int x, y; int x, y;
@ -44,38 +44,33 @@ static int freerdp_bitmap_planar_decompress_plane_rle(BYTE* inPlane, int width,
BYTE* previousScanline; BYTE* previousScanline;
k = 0; k = 0;
pDstData = &pDstData[nChannel];
srcp = inPlane; srcp = pSrcData;
dstp = outPlane; dstp = pDstData;
scanline = width * 4; scanline = nWidth * 4;
previousScanline = NULL; previousScanline = NULL;
y = 0; for (y = 0; y < nHeight; y++)
while (y < height)
{ {
pixel = 0; pixel = 0;
dstp = (outPlane + height * scanline) - ((y + 1) * scanline); dstp = &pDstData[(nHeight - y - 1) * scanline];
currentScanline = dstp; currentScanline = dstp;
x = 0; for (x = 0; x < nWidth; )
while (x < width)
{ {
controlByte = *srcp; controlByte = *srcp;
srcp++; srcp++;
if ((srcp - inPlane) > srcSize) if ((srcp - pSrcData) > SrcSize)
{ {
printf("freerdp_bitmap_planar_decompress_plane_rle: error reading input buffer\n"); printf("planar_decompress_plane_rle: error reading input buffer\n");
return -1; return -1;
} }
nRunLength = PLANAR_CONTROL_BYTE_RUN_LENGTH(controlByte); nRunLength = PLANAR_CONTROL_BYTE_RUN_LENGTH(controlByte);
cRawBytes = PLANAR_CONTROL_BYTE_RAW_BYTES(controlByte); cRawBytes = PLANAR_CONTROL_BYTE_RAW_BYTES(controlByte);
//printf("CONTROL(%d, %d)\n", cRawBytes, nRunLength);
if (nRunLength == 1) if (nRunLength == 1)
{ {
nRunLength = cRawBytes + 16; nRunLength = cRawBytes + 16;
@ -87,23 +82,9 @@ static int freerdp_bitmap_planar_decompress_plane_rle(BYTE* inPlane, int width,
cRawBytes = 0; cRawBytes = 0;
} }
#if 0 if (((dstp + (cRawBytes + nRunLength)) - currentScanline) > nWidth * 4)
printf("y: %d cRawBytes: %d nRunLength: %d\n", y, cRawBytes, nRunLength);
printf("RAW[");
for (k = 0; k < cRawBytes; k++)
{ {
printf("0x%02X%s", srcp[k], printf("planar_decompress_plane_rle: too many pixels in scanline\n");
((k + 1) == cRawBytes) ? "" : ", ");
}
printf("] RUN[%d]\n", nRunLength);
#endif
if (((dstp + (cRawBytes + nRunLength)) - currentScanline) > width * 4)
{
printf("freerdp_bitmap_planar_decompress_plane_rle: too many pixels in scanline\n");
return -1; return -1;
} }
@ -170,107 +151,28 @@ static int freerdp_bitmap_planar_decompress_plane_rle(BYTE* inPlane, int width,
} }
previousScanline = currentScanline; previousScanline = currentScanline;
y++;
} }
return (int) (srcp - inPlane); return (int) (srcp - pSrcData);
} }
static int freerdp_bitmap_planar_decompress_plane_raw(BYTE* srcData, int width, int height, BYTE* dstData, int size) static int planar_decompress_plane_raw(BYTE* pSrcData, UINT32 SrcSize, BYTE* pDstData, int nWidth, int nHeight, int nChannel)
{ {
int x, y; int x, y;
BYTE* srcp = pSrcData;
for (y = 0; y < height; y++) pDstData = &pDstData[nChannel];
for (y = 0; y < nHeight; y++)
{ {
for (x = 0; x < width; x++) for (x = 0; x < nWidth; x++)
{ {
dstData[(((height - y - 1) * width) + x) * 4] = srcData[((y * width) + x)]; pDstData[(((nHeight - y - 1) * nWidth) + x) * 4] = *srcp;
srcp++;
} }
} }
return (width * height); return (nWidth * nHeight);
}
int freerdp_bitmap_planar_decompress(BYTE* srcData, BYTE* dstData, int width, int height, int size)
{
BYTE* srcp;
int dstSize;
BYTE FormatHeader;
srcp = srcData;
FormatHeader = *srcp;
srcp++;
/* AlphaPlane */
if (!(FormatHeader & PLANAR_FORMAT_HEADER_NA))
{
if (FormatHeader & PLANAR_FORMAT_HEADER_RLE)
{
dstSize = freerdp_bitmap_planar_decompress_plane_rle(srcp, width, height, dstData + 3, size - (srcp - srcData));
if (dstSize < 0)
return -1;
srcp += dstSize;
}
else
{
dstSize = freerdp_bitmap_planar_decompress_plane_raw(srcp, width, height, dstData + 3, size - (srcp - srcData));
srcp += dstSize;
}
}
if (FormatHeader & PLANAR_FORMAT_HEADER_RLE)
{
/* LumaOrRedPlane */
dstSize = freerdp_bitmap_planar_decompress_plane_rle(srcp, width, height, dstData + 2, size - (srcp - srcData));
if (dstSize < 0)
return -1;
srcp += dstSize;
/* OrangeChromaOrGreenPlane */
dstSize = freerdp_bitmap_planar_decompress_plane_rle(srcp, width, height, dstData + 1, size - (srcp - srcData));
if (dstSize < 0)
return -1;
srcp += dstSize;
/* GreenChromeOrBluePlane */
dstSize = freerdp_bitmap_planar_decompress_plane_rle(srcp, width, height, dstData + 0, size - (srcp - srcData));
if (dstSize < 0)
return -1;
srcp += dstSize;
}
else
{
/* LumaOrRedPlane */
dstSize = freerdp_bitmap_planar_decompress_plane_raw(srcp, width, height, dstData + 2, size - (srcp - srcData));
srcp += dstSize;
/* OrangeChromaOrGreenPlane */
dstSize = freerdp_bitmap_planar_decompress_plane_raw(srcp, width, height, dstData + 1, size - (srcp - srcData));
srcp += dstSize;
/* GreenChromeOrBluePlane */
dstSize = freerdp_bitmap_planar_decompress_plane_raw(srcp, width, height, dstData + 0, size - (srcp - srcData));
srcp += dstSize;
srcp++;
}
return (size == (srcp - srcData)) ? 0 : -1;
} }
int planar_decompress(BITMAP_PLANAR_CONTEXT* planar, BYTE* pSrcData, UINT32 SrcSize, int planar_decompress(BITMAP_PLANAR_CONTEXT* planar, BYTE* pSrcData, UINT32 SrcSize,
@ -309,8 +211,8 @@ int planar_decompress(BITMAP_PLANAR_CONTEXT* planar, BYTE* pSrcData, UINT32 SrcS
{ {
if (FormatHeader & PLANAR_FORMAT_HEADER_RLE) if (FormatHeader & PLANAR_FORMAT_HEADER_RLE)
{ {
status = freerdp_bitmap_planar_decompress_plane_rle(srcp, nWidth, nHeight, status = planar_decompress_plane_rle(srcp, SrcSize - (srcp - pSrcData),
pDstData + 3, UncompressedSize - (srcp - pSrcData)); pDstData, nWidth, nHeight, 3);
if (status < 0) if (status < 0)
return -1; return -1;
@ -319,8 +221,8 @@ int planar_decompress(BITMAP_PLANAR_CONTEXT* planar, BYTE* pSrcData, UINT32 SrcS
} }
else else
{ {
status = freerdp_bitmap_planar_decompress_plane_raw(srcp, nWidth, nHeight, status = planar_decompress_plane_raw(srcp, SrcSize - (srcp - pSrcData),
pDstData + 3, UncompressedSize - (srcp - pSrcData)); pDstData, nWidth, nHeight, 3);
srcp += status; srcp += status;
} }
@ -330,8 +232,8 @@ int planar_decompress(BITMAP_PLANAR_CONTEXT* planar, BYTE* pSrcData, UINT32 SrcS
{ {
/* LumaOrRedPlane */ /* LumaOrRedPlane */
status = freerdp_bitmap_planar_decompress_plane_rle(srcp, nWidth, nHeight, status = planar_decompress_plane_rle(srcp, SrcSize - (srcp - pSrcData),
pDstData + 2, UncompressedSize - (srcp - pSrcData)); pDstData, nWidth, nHeight, 2);
if (status < 0) if (status < 0)
return -1; return -1;
@ -340,8 +242,8 @@ int planar_decompress(BITMAP_PLANAR_CONTEXT* planar, BYTE* pSrcData, UINT32 SrcS
/* OrangeChromaOrGreenPlane */ /* OrangeChromaOrGreenPlane */
status = freerdp_bitmap_planar_decompress_plane_rle(srcp, nWidth, nHeight, status = planar_decompress_plane_rle(srcp, SrcSize - (srcp - pSrcData),
pDstData + 1, UncompressedSize - (srcp - pSrcData)); pDstData, nWidth, nHeight, 1);
if (status < 0) if (status < 0)
return -1; return -1;
@ -350,8 +252,8 @@ int planar_decompress(BITMAP_PLANAR_CONTEXT* planar, BYTE* pSrcData, UINT32 SrcS
/* GreenChromeOrBluePlane */ /* GreenChromeOrBluePlane */
status = freerdp_bitmap_planar_decompress_plane_rle(srcp, nWidth, nHeight, status = planar_decompress_plane_rle(srcp, SrcSize - (srcp - pSrcData),
pDstData + 0, UncompressedSize - (srcp - pSrcData)); pDstData, nWidth, nHeight, 0);
if (status < 0) if (status < 0)
return -1; return -1;
@ -362,25 +264,28 @@ int planar_decompress(BITMAP_PLANAR_CONTEXT* planar, BYTE* pSrcData, UINT32 SrcS
{ {
/* LumaOrRedPlane */ /* LumaOrRedPlane */
status = freerdp_bitmap_planar_decompress_plane_raw(srcp, nWidth, nHeight, status = planar_decompress_plane_raw(srcp, SrcSize - (srcp - pSrcData),
pDstData + 2, UncompressedSize - (srcp - pSrcData)); pDstData, nWidth, nHeight, 2);
srcp += status; srcp += status;
/* OrangeChromaOrGreenPlane */ /* OrangeChromaOrGreenPlane */
status = freerdp_bitmap_planar_decompress_plane_raw(srcp, nWidth, nHeight, status = planar_decompress_plane_raw(srcp, SrcSize - (srcp - pSrcData),
pDstData + 1, UncompressedSize - (srcp - pSrcData)); pDstData, nWidth, nHeight, 1);
srcp += status; srcp += status;
/* GreenChromeOrBluePlane */ /* GreenChromeOrBluePlane */
status = freerdp_bitmap_planar_decompress_plane_raw(srcp, nWidth, nHeight, status = planar_decompress_plane_raw(srcp, SrcSize - (srcp - pSrcData),
pDstData + 0, UncompressedSize - (srcp - pSrcData)); pDstData, nWidth, nHeight, 0);
srcp += status; srcp += status;
srcp++; srcp++;
} }
status = (UncompressedSize == (srcp - pSrcData)) ? 1 : -1; status = (SrcSize == (srcp - pSrcData)) ? 1 : -1;
return status; return status;
} }