summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk/channel-display-priv.h1
-rw-r--r--gtk/channel-display.c4
-rw-r--r--gtk/decode-zlib.c66
-rw-r--r--gtk/decode.h3
4 files changed, 73 insertions, 1 deletions
diff --git a/gtk/channel-display-priv.h b/gtk/channel-display-priv.h
index ae8c5e8..ab8268c 100644
--- a/gtk/channel-display-priv.h
+++ b/gtk/channel-display-priv.h
@@ -44,6 +44,7 @@ typedef struct display_surface {
uint8_t *data;
SpiceCanvas *canvas;
SpiceGlzDecoder *glz_decoder;
+ SpiceZlibDecoder *zlib_decoder;
} display_surface;
typedef struct display_stream {
diff --git a/gtk/channel-display.c b/gtk/channel-display.c
index d1c2e0d..275d375 100644
--- a/gtk/channel-display.c
+++ b/gtk/channel-display.c
@@ -313,6 +313,7 @@ static int create_canvas(SpiceChannel *channel, display_surface *surface)
c->glz_window = glz_decoder_window_new();
}
surface->glz_decoder = glz_decoder_new(c->glz_window);
+ surface->zlib_decoder = zlib_decoder_new();
surface->canvas = canvas_create_for_data(surface->width,
surface->height,
@@ -326,7 +327,7 @@ static int create_canvas(SpiceChannel *channel, display_surface *surface)
NULL, // &csurfaces.base,
surface->glz_decoder,
NULL, // &jpeg_decoder(),
- NULL); // &zlib_decoder());
+ surface->zlib_decoder);
g_return_val_if_fail(surface->canvas != NULL, 0);
return 0;
@@ -338,6 +339,7 @@ static void destroy_canvas(display_surface *surface)
return;
glz_decoder_destroy(surface->glz_decoder);
+ zlib_decoder_destroy(surface->zlib_decoder);
if (surface->shmid == -1) {
free(surface->data);
diff --git a/gtk/decode-zlib.c b/gtk/decode-zlib.c
index 8491541..892713e 100644
--- a/gtk/decode-zlib.c
+++ b/gtk/decode-zlib.c
@@ -16,3 +16,69 @@
License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "decode.h"
+
+#define ZLIB_WINAPI
+#include <zlib.h>
+
+typedef struct GlibZlibDecoder
+{
+ SpiceZlibDecoder base;
+ z_stream _z_strm;
+} GlibZlibDecoder;
+
+static void decode(SpiceZlibDecoder *decoder,
+ uint8_t *data, int data_size,
+ uint8_t *dest, int dest_size)
+{
+ GlibZlibDecoder *d = SPICE_CONTAINEROF(decoder, GlibZlibDecoder, base);
+ int z_ret;
+
+ inflateReset(&d->_z_strm);
+ d->_z_strm.next_in = data;
+ d->_z_strm.avail_in = data_size;
+ d->_z_strm.next_out = dest;
+ d->_z_strm.avail_out = dest_size;
+
+ z_ret = inflate(&d->_z_strm, Z_FINISH);
+
+ if (z_ret != Z_STREAM_END) {
+ g_warning("zlib inflate failed, error %d", z_ret);
+ }
+}
+
+static SpiceZlibDecoderOps zlib_decoder_ops = {
+ .decode = decode,
+};
+
+SpiceZlibDecoder *zlib_decoder_new(void)
+{
+ GlibZlibDecoder *d = spice_new0(GlibZlibDecoder, 1);
+ int z_ret;
+
+ d->_z_strm.zalloc = Z_NULL;
+ d->_z_strm.zfree = Z_NULL;
+ d->_z_strm.opaque = Z_NULL;
+ d->_z_strm.next_in = Z_NULL;
+ d->_z_strm.avail_in = 0;
+ z_ret = inflateInit(&d->_z_strm);
+ if (z_ret != Z_OK) {
+ g_warning("zlib decoder init failed, error %d", z_ret);
+ goto fail;
+ }
+
+ d->base.ops = &zlib_decoder_ops;
+
+ return &d->base;
+
+fail:
+ free(d);
+ return NULL;
+}
+
+void zlib_decoder_destroy(SpiceZlibDecoder *decoder)
+{
+ GlibZlibDecoder *d = SPICE_CONTAINEROF(decoder, GlibZlibDecoder, base);
+
+ inflateEnd(&d->_z_strm);
+ free(d);
+}
diff --git a/gtk/decode.h b/gtk/decode.h
index 42bb713..c2e21d5 100644
--- a/gtk/decode.h
+++ b/gtk/decode.h
@@ -31,6 +31,9 @@ void glz_decoder_window_destroy(SpiceGlzDecoderWindow *w);
SpiceGlzDecoder *glz_decoder_new(SpiceGlzDecoderWindow *w);
void glz_decoder_destroy(SpiceGlzDecoder *d);
+SpiceZlibDecoder *zlib_decoder_new(void);
+void zlib_decoder_destroy(SpiceZlibDecoder *d);
+
G_END_DECLS
#endif // SPICEGTK_DECODE_H_