[Spice-commits] common/canvas_base.c common/draw.h spice-protocol spice.proto

Christophe Fergau teuf at kemper.freedesktop.org
Tue Dec 2 10:25:06 PST 2014


 common/canvas_base.c |   71 +++++++++++++++++++++++++++++++++++++++++++++++++++
 common/draw.h        |    3 +-
 spice-protocol       |    2 -
 spice.proto          |    3 ++
 4 files changed, 77 insertions(+), 2 deletions(-)

New commits:
commit 5b3cdad921d32c9294377efac61243a09f849d08
Author: Javier Celaya <javier.celaya at flexvm.es>
Date:   Wed Oct 22 09:58:29 2014 +0200

    Add LZ4 image compression support.
    
    - Add a new LZ4 image type to spice.proto.
    - Add canvas_get_lz4() to common_canvas_base, to get a pixmap from an
      lz4 image.
    - Add an enable-lz4 switch to the configure script, disabled by default.

diff --git a/common/canvas_base.c b/common/canvas_base.c
index 2753fae..a1bfc27 100644
--- a/common/canvas_base.c
+++ b/common/canvas_base.c
@@ -26,6 +26,10 @@
 #include <stdio.h>
 #include <math.h>
 
+#ifdef USE_LZ4
+#include <arpa/inet.h>
+#include <lz4.h>
+#endif
 #include <spice/macros.h>
 #include "log.h"
 #include "quic.h"
@@ -543,6 +547,64 @@ static pixman_image_t *canvas_get_jpeg(CanvasBase *canvas, SpiceImage *image, in
     return surface;
 }
 
+#ifdef USE_LZ4
+static pixman_image_t *canvas_get_lz4(CanvasBase *canvas, SpiceImage *image, int invers)
+{
+    pixman_image_t *surface = NULL;
+    int dec_size, enc_size;
+    int stride;
+    int stride_abs;
+    uint8_t *dest, *data, *data_end;
+    int width, height, direction;
+    LZ4_streamDecode_t *stream;
+
+    spice_chunks_linearize(image->u.lz4.data);
+    data = image->u.lz4.data->chunk[0].data;
+    data_end = data + image->u.lz4.data->chunk[0].len;
+    width = image->descriptor.width;
+    height = image->descriptor.height;
+    direction = *(data++);
+
+    surface = surface_create(
+#ifdef WIN32
+                             canvas->dc,
+#endif
+                             PIXMAN_a8r8g8b8,
+                             width, height, direction == 0);
+    if (surface == NULL) {
+        spice_warning("create surface failed");
+        return NULL;
+    }
+
+    stream = LZ4_createStreamDecode();
+    dest = (uint8_t *)pixman_image_get_data(surface);
+    stride = pixman_image_get_stride(surface);
+    stride_abs = abs(stride);
+    if (direction == 1) {
+        dest -= (stride_abs * (height - 1));
+    }
+
+    do {
+        // Read next compressed block
+        enc_size = ntohl(*((uint32_t *)data));
+        data += 4;
+        dec_size = LZ4_decompress_safe_continue(stream, (const char *) data,
+                                                (char *) dest, enc_size, height * stride_abs);
+        if (dec_size <= 0) {
+            spice_warning("Error decoding LZ4 block\n");
+            pixman_image_unref(surface);
+            surface = NULL;
+            break;
+        }
+        dest += dec_size;
+        data += enc_size;
+    } while (data < data_end);
+
+    LZ4_freeStreamDecode(stream);
+    return surface;
+}
+#endif
+
 static pixman_image_t *canvas_get_jpeg_alpha(CanvasBase *canvas,
                                              SpiceImage *image, int invers)
 {
@@ -1119,6 +1181,15 @@ static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SpiceImage
         surface = canvas_get_jpeg_alpha(canvas, image, 0);
         break;
     }
+    case SPICE_IMAGE_TYPE_LZ4: {
+#ifdef USE_LZ4
+        surface = canvas_get_lz4(canvas, image, 0);
+#else
+        spice_warning("Lz4 compression algorithm not supported.\n");
+        surface = NULL;
+#endif
+        break;
+    }
 #if defined(SW_CANVAS_CACHE)
     case SPICE_IMAGE_TYPE_GLZ_RGB: {
         surface = canvas_get_glz(canvas, image, want_original);
diff --git a/common/draw.h b/common/draw.h
index 3704358..1155dc5 100644
--- a/common/draw.h
+++ b/common/draw.h
@@ -120,7 +120,7 @@ typedef struct SpiceSurface {
 typedef struct SpiceQUICData {
     uint32_t data_size;
     SpiceChunks *data;
-} SpiceQUICData, SpiceLZRGBData, SpiceJPEGData;
+} SpiceQUICData, SpiceLZRGBData, SpiceJPEGData, SpiceLZ4Data;
 
 typedef struct SpiceLZPLTData {
     uint8_t flags;
@@ -153,6 +153,7 @@ typedef struct SpiceImage {
         SpiceLZRGBData      lz_rgb;
         SpiceLZPLTData      lz_plt;
         SpiceJPEGData       jpeg;
+        SpiceLZ4Data        lz4;
         SpiceZlibGlzRGBData zlib_glz;
         SpiceJPEGAlphaData  jpeg_alpha;
     } u;
diff --git a/spice-protocol b/spice-protocol
index 58c1b4a..7566c5b 160000
--- a/spice-protocol
+++ b/spice-protocol
@@ -1 +1 @@
-Subproject commit 58c1b4aeb85167c44fea0813771d1c33c9acacb7
+Subproject commit 7566c5b3ad47b0b487e15b58d72e151882d05541
diff --git a/spice.proto b/spice.proto
index 316d287..01493c9 100644
--- a/spice.proto
+++ b/spice.proto
@@ -358,6 +358,7 @@ enum8 image_type {
     FROM_CACHE_LOSSLESS,
     ZLIB_GLZ_RGB,
     JPEG_ALPHA,
+    LZ4,
 };
 
 flags8 image_flags {
@@ -568,6 +569,8 @@ struct Image {
         BinaryData lz_rgb;
     case JPEG:
         BinaryData jpeg;
+    case LZ4:
+        BinaryData lz4;
     case LZ_PLT:
         LZPLTData lz_plt;
     case ZLIB_GLZ_RGB:


More information about the Spice-commits mailing list