libfreerdp-codec: start offering more flexible planar codec decompression

This commit is contained in:
Marc-André Moreau 2014-06-17 16:44:24 -04:00
parent d69316198f
commit 425763d30a
3 changed files with 117 additions and 8 deletions

View File

@ -294,7 +294,6 @@ int xf_SurfaceCommand_ClearCodec(xfContext* xfc, RdpgfxClientContext* context, R
int xf_SurfaceCommand_Planar(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) int xf_SurfaceCommand_Planar(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd)
{ {
int status; int status;
UINT32 DstSize = 0;
BYTE* DstData = NULL; BYTE* DstData = NULL;
xfGfxSurface* surface; xfGfxSurface* surface;
RECTANGLE_16 invalidRect; RECTANGLE_16 invalidRect;
@ -304,13 +303,8 @@ int xf_SurfaceCommand_Planar(xfContext* xfc, RdpgfxClientContext* context, RDPGF
if (!surface) if (!surface)
return -1; return -1;
DstSize = cmd->width * cmd->height * 4; status = planar_decompress(NULL, cmd->data, cmd->length, &DstData,
DstData = (BYTE*) malloc(DstSize); PIXEL_FORMAT_XRGB32, cmd->width * 4, 0, 0, cmd->width, cmd->height);
if (!DstData)
return -1;
status = freerdp_bitmap_planar_decompress(cmd->data, DstData, cmd->width, cmd->height, cmd->length);
freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top,
cmd->width, cmd->height, DstData, PIXEL_FORMAT_XRGB32_VF, cmd->width * 4, 0, 0); cmd->width, cmd->height, DstData, PIXEL_FORMAT_XRGB32_VF, cmd->width * 4, 0, 0);

View File

@ -48,4 +48,7 @@ FREERDP_API BYTE* freerdp_bitmap_compress_planar(BITMAP_PLANAR_CONTEXT* context,
FREERDP_API BITMAP_PLANAR_CONTEXT* freerdp_bitmap_planar_context_new(DWORD flags, int maxWidth, int maxHeight); FREERDP_API BITMAP_PLANAR_CONTEXT* freerdp_bitmap_planar_context_new(DWORD flags, int maxWidth, int maxHeight);
FREERDP_API void freerdp_bitmap_planar_context_free(BITMAP_PLANAR_CONTEXT* context); FREERDP_API void freerdp_bitmap_planar_context_free(BITMAP_PLANAR_CONTEXT* context);
FREERDP_API int planar_decompress(BITMAP_PLANAR_CONTEXT* planar, BYTE* pSrcData, UINT32 SrcSize,
BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight);
#endif /* FREERDP_CODEC_BITMAP_H */ #endif /* FREERDP_CODEC_BITMAP_H */

View File

@ -273,6 +273,118 @@ int freerdp_bitmap_planar_decompress(BYTE* srcData, BYTE* dstData, int width, in
return (size == (srcp - srcData)) ? 0 : -1; return (size == (srcp - srcData)) ? 0 : -1;
} }
int planar_decompress(BITMAP_PLANAR_CONTEXT* planar, BYTE* pSrcData, UINT32 SrcSize,
BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight)
{
int status;
BYTE* srcp;
BYTE FormatHeader;
BYTE* pDstData = NULL;
UINT32 UncompressedSize;
if ((nWidth * nHeight) <= 0)
return -1;
srcp = pSrcData;
UncompressedSize = nWidth * nHeight * 4;
pDstData = *ppDstData;
if (!pDstData)
{
pDstData = (BYTE*) malloc(UncompressedSize);
if (!pDstData)
return -1;
*ppDstData = pDstData;
}
FormatHeader = *srcp;
srcp++;
/* AlphaPlane */
if (!(FormatHeader & PLANAR_FORMAT_HEADER_NA))
{
if (FormatHeader & PLANAR_FORMAT_HEADER_RLE)
{
status = freerdp_bitmap_planar_decompress_plane_rle(srcp, nWidth, nHeight,
pDstData + 3, UncompressedSize - (srcp - pSrcData));
if (status < 0)
return -1;
srcp += status;
}
else
{
status = freerdp_bitmap_planar_decompress_plane_raw(srcp, nWidth, nHeight,
pDstData + 3, UncompressedSize - (srcp - pSrcData));
srcp += status;
}
}
if (FormatHeader & PLANAR_FORMAT_HEADER_RLE)
{
/* LumaOrRedPlane */
status = freerdp_bitmap_planar_decompress_plane_rle(srcp, nWidth, nHeight,
pDstData + 2, UncompressedSize - (srcp - pSrcData));
if (status < 0)
return -1;
srcp += status;
/* OrangeChromaOrGreenPlane */
status = freerdp_bitmap_planar_decompress_plane_rle(srcp, nWidth, nHeight,
pDstData + 1, UncompressedSize - (srcp - pSrcData));
if (status < 0)
return -1;
srcp += status;
/* GreenChromeOrBluePlane */
status = freerdp_bitmap_planar_decompress_plane_rle(srcp, nWidth, nHeight,
pDstData + 0, UncompressedSize - (srcp - pSrcData));
if (status < 0)
return -1;
srcp += status;
}
else
{
/* LumaOrRedPlane */
status = freerdp_bitmap_planar_decompress_plane_raw(srcp, nWidth, nHeight,
pDstData + 2, UncompressedSize - (srcp - pSrcData));
srcp += status;
/* OrangeChromaOrGreenPlane */
status = freerdp_bitmap_planar_decompress_plane_raw(srcp, nWidth, nHeight,
pDstData + 1, UncompressedSize - (srcp - pSrcData));
srcp += status;
/* GreenChromeOrBluePlane */
status = freerdp_bitmap_planar_decompress_plane_raw(srcp, nWidth, nHeight,
pDstData + 0, UncompressedSize - (srcp - pSrcData));
srcp += status;
srcp++;
}
status = (UncompressedSize == (srcp - pSrcData)) ? 1 : -1;
return status;
}
int freerdp_split_color_planes(BYTE* data, UINT32 format, int width, int height, int scanline, BYTE* planes[4]) int freerdp_split_color_planes(BYTE* data, UINT32 format, int width, int height, int scanline, BYTE* planes[4])
{ {
int bpp; int bpp;