libfreerdp-rfx: support encoding 4-bit and 8-bit palette pixel format.
authorVic Lee <llyzs@163.com>
Wed, 14 Sep 2011 17:48:08 +0000 (01:48 +0800)
committerVic Lee <llyzs@163.com>
Wed, 14 Sep 2011 17:48:08 +0000 (01:48 +0800)
include/freerdp/rfx/rfx.h
libfreerdp-rfx/librfx.c
libfreerdp-rfx/rfx_encode.c

index 66a62bd..50eac7b 100644 (file)
@@ -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;
index dd1d407..56471f0 100644 (file)
@@ -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);
index 9cf005e..0396ac8 100644 (file)
@@ -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);