diff options
-rw-r--r-- | gtk/channel-display-priv.h | 1 | ||||
-rw-r--r-- | gtk/channel-display.c | 4 | ||||
-rw-r--r-- | gtk/decode-zlib.c | 66 | ||||
-rw-r--r-- | gtk/decode.h | 3 |
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_ |