From 4abe7a69239e5e67255e308e95062b305e2daca6 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Thu, 15 Sep 2011 01:48:08 +0800 Subject: [PATCH] libfreerdp-rfx: support encoding 4-bit and 8-bit palette pixel format. --- include/freerdp/rfx/rfx.h | 9 +++++++-- libfreerdp-rfx/librfx.c | 16 +++++++++++----- libfreerdp-rfx/rfx_encode.c | 38 +++++++++++++++++++++++++++++++++++-- 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/include/freerdp/rfx/rfx.h b/include/freerdp/rfx/rfx.h index 66a62bd38..50eac7b0f 100644 --- a/include/freerdp/rfx/rfx.h +++ b/include/freerdp/rfx/rfx.h @@ -42,7 +42,9 @@ enum _RFX_PIXEL_FORMAT RFX_PIXEL_FORMAT_BGR, RFX_PIXEL_FORMAT_RGB, RFX_PIXEL_FORMAT_BGR565_LE, - RFX_PIXEL_FORMAT_RGB565_LE + RFX_PIXEL_FORMAT_RGB565_LE, + RFX_PIXEL_FORMAT_PALETTE4_PLANER, + RFX_PIXEL_FORMAT_PALETTE8 }; typedef enum _RFX_PIXEL_FORMAT RFX_PIXEL_FORMAT; @@ -96,7 +98,10 @@ struct _RFX_CONTEXT uint32 codec_id; uint32 codec_version; RFX_PIXEL_FORMAT pixel_format; - uint8 bytes_per_pixel; + uint8 bits_per_pixel; + + /* color palette allocated by the application */ + const uint8* palette; /* temporary data within a frame */ uint32 frame_idx; diff --git a/libfreerdp-rfx/librfx.c b/libfreerdp-rfx/librfx.c index dd1d4077e..56471f09a 100644 --- a/libfreerdp-rfx/librfx.c +++ b/libfreerdp-rfx/librfx.c @@ -183,18 +183,24 @@ void rfx_context_set_pixel_format(RFX_CONTEXT* context, RFX_PIXEL_FORMAT pixel_f { case RFX_PIXEL_FORMAT_BGRA: case RFX_PIXEL_FORMAT_RGBA: - context->bytes_per_pixel = 4; + context->bits_per_pixel = 32; break; case RFX_PIXEL_FORMAT_BGR: case RFX_PIXEL_FORMAT_RGB: - context->bytes_per_pixel = 3; + context->bits_per_pixel = 24; break; case RFX_PIXEL_FORMAT_BGR565_LE: case RFX_PIXEL_FORMAT_RGB565_LE: - context->bytes_per_pixel = 2; + context->bits_per_pixel = 16; + break; + case RFX_PIXEL_FORMAT_PALETTE4_PLANER: + context->bits_per_pixel = 4; + break; + case RFX_PIXEL_FORMAT_PALETTE8: + context->bits_per_pixel = 8; break; default: - context->bytes_per_pixel = 0; + context->bits_per_pixel = 0; break; } } @@ -802,7 +808,7 @@ static void rfx_compose_message_tileset(RFX_CONTEXT* context, STREAM* data_out, for (xIdx = 0; xIdx < numTilesX; xIdx++) { rfx_compose_message_tile(context, data_out, - image_data + yIdx * 64 * rowstride + xIdx * 64 * context->bytes_per_pixel, + image_data + yIdx * 64 * rowstride + xIdx * 8 * context->bits_per_pixel, xIdx < numTilesX - 1 ? 64 : width - xIdx * 64, yIdx < numTilesY - 1 ? 64 : height - yIdx * 64, rowstride, quantVals, quantIdxY, quantIdxCb, quantIdxCr, xIdx, yIdx); diff --git a/libfreerdp-rfx/rfx_encode.c b/libfreerdp-rfx/rfx_encode.c index 9cf005e3c..0396ac8b6 100644 --- a/libfreerdp-rfx/rfx_encode.c +++ b/libfreerdp-rfx/rfx_encode.c @@ -31,7 +31,7 @@ #define MINMAX(_v,_l,_h) ((_v) < (_l) ? (_l) : ((_v) > (_h) ? (_h) : (_v))) static void rfx_encode_format_rgb(const uint8* rgb_data, int width, int height, int rowstride, - RFX_PIXEL_FORMAT pixel_format, sint16* r_buf, sint16* g_buf, sint16* b_buf) + RFX_PIXEL_FORMAT pixel_format, const uint8* palette, sint16* r_buf, sint16* g_buf, sint16* b_buf) { int x, y; int x_exceed; @@ -100,6 +100,40 @@ static void rfx_encode_format_rgb(const uint8* rgb_data, int width, int height, src += 2; } break; + case RFX_PIXEL_FORMAT_PALETTE4_PLANER: + if (!palette) + break; + for (x = 0; x < width; x++) + { + int shift; + uint8 idx; + + shift = (7 - (x % 8)); + idx = ((*src) >> shift) & 1; + idx |= (((*(src + 1)) >> shift) & 1) << 1; + idx |= (((*(src + 2)) >> shift) & 1) << 2; + idx |= (((*(src + 3)) >> shift) & 1) << 3; + idx *= 3; + *r_buf++ = (sint16) palette[idx]; + *g_buf++ = (sint16) palette[idx + 1]; + *b_buf++ = (sint16) palette[idx + 2]; + if (shift == 0) + src += 4; + } + break; + case RFX_PIXEL_FORMAT_PALETTE8: + if (!palette) + break; + for (x = 0; x < width; x++) + { + int idx = (*src) * 3; + + *r_buf++ = (sint16) palette[idx]; + *g_buf++ = (sint16) palette[idx + 1]; + *b_buf++ = (sint16) palette[idx + 2]; + src++; + } + break; default: break; } @@ -211,7 +245,7 @@ void rfx_encode_rgb(RFX_CONTEXT* context, const uint8* rgb_data, int width, int PROFILER_ENTER(context->priv->prof_rfx_encode_format_rgb); rfx_encode_format_rgb(rgb_data, width, height, rowstride, - context->pixel_format, y_r_buffer, cb_g_buffer, cr_b_buffer); + context->pixel_format, context->palette, y_r_buffer, cb_g_buffer, cr_b_buffer); PROFILER_EXIT(context->priv->prof_rfx_encode_format_rgb); PROFILER_ENTER(context->priv->prof_rfx_encode_rgb_to_ycbcr);