> > This only adds a basic test relying on gdk-pixbuf. > The main limitation is that gdk-pixbuf does not handle 16bpp images, > nor 32bpp/no alpha images. I should have picked something else instead ;) > > This allows at least to exercise the QUIC_IMAGE_TYPE_RGB24 and > QUIC_IMAGE_TYPE_RGBA codepaths. > > Signed-off-by: Christophe Fergeau <cfergeau@xxxxxxxxxx> > --- > configure.ac | 1 + > m4/spice-deps.m4 | 15 ++++ > tests/Makefile.am | 22 +++++ > tests/test-quic.c | 235 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 273 insertions(+) > create mode 100644 tests/test-quic.c > > diff --git a/configure.ac b/configure.ac > index 3542161..1f2ecc0 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -47,6 +47,7 @@ SPICE_CHECK_CELT051 > SPICE_CHECK_GLIB2 > SPICE_CHECK_OPUS > SPICE_CHECK_OPENSSL > +SPICE_CHECK_GDK_PIXBUF > > SPICE_COMMON_CFLAGS='$(PIXMAN_CFLAGS) $(SMARTCARD_CFLAGS) $(CELT051_CFLAGS) > $(GLIB2_CFLAGS) $(OPUS_CFLAGS) $(OPENSSL_CFLAGS)' > SPICE_COMMON_CFLAGS="$SPICE_COMMON_CFLAGS -DG_LOG_DOMAIN=\\\"Spice\\\"" > diff --git a/m4/spice-deps.m4 b/m4/spice-deps.m4 > index 68e3091..3fe4a5b 100644 > --- a/m4/spice-deps.m4 > +++ b/m4/spice-deps.m4 > @@ -147,6 +147,21 @@ AC_DEFUN([SPICE_CHECK_GLIB2], [ > PKG_CHECK_MODULES(GLIB2, glib-2.0 >= 2.22 gio-2.0 >= 2.22 gthread-2.0 >= > 2.22) > ]) > > +# SPICE_CHECK_GDK_PIXBUF > +# ---------------------- > +# Check for the availability of gdk-pixbuf. If found, it will return the > flags to use > +# in the GDK_PIXBUF_CFLAGS and GDK_PIXBUF_LIBS variables, and it will define > a > +# HAVE_GDK_PIXBUF preprocessor symbol as well as a HAVE_GDK_PIXBUF Makefile > conditional. > +# ---------------- > +AC_DEFUN([SPICE_CHECK_GDK_PIXBUF], [ > + PKG_CHECK_MODULES([GDK_PIXBUF], [gdk-pixbuf-2.0], [have_gdk_pixbuf=yes], > [have_gdk_pixbuf=no]) > + > + AM_CONDITIONAL([HAVE_GDK_PIXBUF], [test "x$have_gdk_pixbuf" = "xyes"]) > + if test "x$have_gdk_pixbuf" = "xyes" ; then > + AC_DEFINE([HAVE_GDK_PIXBUF], [1], [Define if gdk-pixbuf was found]) > + fi > +]) > + > # SPICE_CHECK_PYTHON_MODULES() > # -------------------------- > # Adds a --enable-python-checks configure flags as well as checks for the > diff --git a/tests/Makefile.am b/tests/Makefile.am > index 10033c0..02f679d 100644 > --- a/tests/Makefile.am > +++ b/tests/Makefile.am > @@ -1,6 +1,9 @@ > NULL = > > TESTS = test_logging test_marshallers > +if HAVE_GDK_PIXBUF > +TESTS += test_quic > +endif I would put these with other lines > noinst_PROGRAMS = $(TESTS) > > test_logging_SOURCES = test-logging.c > @@ -33,6 +36,25 @@ test_marshallers_LDADD = \ > $(GLIB2_LIBS) \ > $(NULL) > > + > +if HAVE_GDK_PIXBUF so here TESTS += test_quic > +test_quic_SOURCES = \ > + test-quic.c \ > + $(NULL) > +test_quic_CFLAGS = \ > + -I$(top_srcdir) \ > + $(GLIB2_CFLAGS) \ > + $(GDK_PIXBUF_CFLAGS) \ > + $(PROTOCOL_CFLAGS) \ > + $(NULL) > +test_quic_LDADD = \ > + $(top_builddir)/common/libspice-common.la \ > + $(GLIB2_LIBS) \ > + $(GDK_PIXBUF_LIBS) \ > + $(NULL) > +endif > + > + Maybe you want also to add test-quic.c to EXTRA_DIST in order to be able to build a proper package if gdk-pixbuf is missing. > # Avoid need for python(pyparsing) by end users > TEST_MARSHALLERS = \ > generated_test_marshallers.c \ > diff --git a/tests/test-quic.c b/tests/test-quic.c > new file mode 100644 > index 0000000..b45794f > --- /dev/null > +++ b/tests/test-quic.c > @@ -0,0 +1,235 @@ I would put a license. > +#include "common/quic.h" shouldn't you include config.h (or syntax checks would fail) ? > +#include <glib.h> > +#include <gdk-pixbuf/gdk-pixbuf.h> I would include these first. > + > +typedef struct { > + QuicUsrContext usr; > + GByteArray *dest; > +} QuicData; > + > +static SPICE_GNUC_NORETURN SPICE_GNUC_PRINTF(2, 3) void > +quic_usr_error(QuicUsrContext *usr, const char *fmt, ...) > +{ > + va_list ap; > + > + va_start(ap, fmt); > + g_logv(G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, fmt, ap); > + va_end(ap); > + > + g_assert_not_reached(); > +} > + > +static SPICE_GNUC_PRINTF(2, 3) void > +quic_usr_warn(QuicUsrContext *usr, const char *fmt, ...) > +{ > + va_list ap; > + > + va_start(ap, fmt); > + g_logv(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, fmt, ap); > + va_end(ap); > +} > + > +static void *quic_usr_malloc(QuicUsrContext *usr, int size) > +{ > + return g_malloc(size); > +} > + > + > +static void quic_usr_free(QuicUsrContext *usr, void *ptr) > +{ > + g_free(ptr); > +} > + > +static int quic_usr_more_space(QuicUsrContext *usr, uint32_t **io_ptr, int > rows_completed) > +{ > + QuicData *quic_data = (QuicData *)usr; > + int initial_len = quic_data->dest->len; > + > + g_byte_array_set_size(quic_data->dest, quic_data->dest->len*2); > + > + *io_ptr = (uint32_t *)(quic_data->dest->data + initial_len); > + return (quic_data->dest->len - initial_len)/4; > +} > + > + > +static int quic_usr_more_lines(QuicUsrContext *usr, uint8_t **lines) > +{ > + g_return_val_if_reached(0); > +} > + > + > +static void init_quic_data(QuicData *quic_data) > +{ > + quic_data->usr.error = quic_usr_error; > + quic_data->usr.warn = quic_usr_warn; > + quic_data->usr.info = quic_usr_warn; > + quic_data->usr.malloc = quic_usr_malloc; > + quic_data->usr.free = quic_usr_free; > + quic_data->usr.more_space = quic_usr_more_space; > + quic_data->usr.more_lines = quic_usr_more_lines; > + quic_data->dest = g_byte_array_new(); > +} > + > +static GByteArray *quic_encode_from_pixbuf(GdkPixbuf *pixbuf) > +{ > + QuicData quic_data; > + QuicContext *quic; > + int encoded_size; > + QuicImageType quic_type; > + > + init_quic_data(&quic_data); > + g_byte_array_set_size(quic_data.dest, 1024); > + > + quic = quic_create(&quic_data.usr); > + g_assert(quic != NULL); > + switch (gdk_pixbuf_get_n_channels(pixbuf)) { > + case 3: > + quic_type = QUIC_IMAGE_TYPE_RGB24; > + break; > + case 4: > + quic_type = QUIC_IMAGE_TYPE_RGBA; > + break; > + default: > + g_assert_not_reached(); > + } > + encoded_size = quic_encode(quic, quic_type, > + gdk_pixbuf_get_width(pixbuf), > + gdk_pixbuf_get_height(pixbuf), > + gdk_pixbuf_get_pixels(pixbuf), > + gdk_pixbuf_get_height(pixbuf), > + gdk_pixbuf_get_rowstride(pixbuf), > + (uint32_t *)quic_data.dest->data, > + quic_data.dest->len/sizeof(uint32_t)); > + encoded_size *= 4; > + g_byte_array_set_size(quic_data.dest, encoded_size); > + quic_destroy(quic); > + > + return quic_data.dest; > +} > + > +static GdkPixbuf *quic_decode_to_pixbuf(GByteArray *compressed_data) > +{ > + QuicData quic_data; > + QuicContext *quic; > + int encoded_size; > + QuicImageType quic_type; > + GdkPixbuf *pixbuf; > + QuicImageType type; > + int width; > + int height; > + int status; > + > + init_quic_data(&quic_data); > + g_byte_array_free(quic_data.dest, TRUE); > + quic_data.dest = NULL; > + > + quic = quic_create(&quic_data.usr); > + g_assert(quic != NULL); > + > + status = quic_decode_begin(quic, > + (uint32_t *)compressed_data->data, > compressed_data->len/4, > + &type, &width, &height); > + g_assert(status == QUIC_OK); > + > + pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, > + (type == QUIC_IMAGE_TYPE_RGBA), 8, > + width, height); > + status = quic_decode(quic, type, > + gdk_pixbuf_get_pixels(pixbuf), > + gdk_pixbuf_get_rowstride(pixbuf)); > + g_assert(status == QUIC_OK); > + quic_destroy(quic); > + > + return pixbuf; > +} > + > +static void gdk_pixbuf_compare(GdkPixbuf *pixbuf_a, GdkPixbuf *pixbuf_b) > +{ > + int width = gdk_pixbuf_get_width(pixbuf_a); > + int height = gdk_pixbuf_get_height(pixbuf_a); > + int n_channels = gdk_pixbuf_get_n_channels (pixbuf_a); > + int x; > + int y; > + guint8 *pixels_a = gdk_pixbuf_get_pixels(pixbuf_a); > + guint8 *pixels_b = gdk_pixbuf_get_pixels(pixbuf_a); > + > + g_assert(width == gdk_pixbuf_get_width(pixbuf_b)); > + g_assert(height == gdk_pixbuf_get_height(pixbuf_b)); > + g_assert(n_channels == gdk_pixbuf_get_n_channels (pixbuf_b)); > + for (y = 0; y < height; y++) { > + for (x = 0; x < width; x++) { > + guint8 *p_a = pixels_a + y*gdk_pixbuf_get_rowstride(pixbuf_a) + > x*n_channels; > + guint8 *p_b = pixels_b + y*gdk_pixbuf_get_rowstride(pixbuf_b) + > x*n_channels; > + > + g_assert(p_a[0] == p_b[0]); > + g_assert(p_a[1] == p_b[1]); > + g_assert(p_a[2] == p_b[2]); > + if (gdk_pixbuf_get_has_alpha(pixbuf_a)) { > + g_assert(p_a[3] == p_b[3]); > + } > + } > + } > +} > + > +static GdkPixbuf *gdk_pixbuf_new_random(void) > +{ > + gboolean has_alpha = g_random_boolean(); > + gint n_channels = g_random_int_range(3, 5); > + gint width = g_random_int_range(100, 2000); > + gint height = g_random_int_range(100, 2000); > + GdkPixbuf *random_pixbuf; > + gint i; > + guint8 *pixels; > + > + random_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, has_alpha, 8, width, > height); > + pixels = gdk_pixbuf_get_pixels(random_pixbuf); > + for (i = 0; i < gdk_pixbuf_get_byte_length(random_pixbuf); i++) { > + pixels[i] = g_random_int_range(0, 256); > + } > + > + return random_pixbuf; > +} > + > +static void test_pixbuf(GdkPixbuf *pixbuf) > +{ > + GdkPixbuf *uncompressed_pixbuf; > + GByteArray *compressed_data; > + g_assert(pixbuf != NULL); > + g_assert (gdk_pixbuf_get_colorspace(pixbuf) == GDK_COLORSPACE_RGB); > + g_assert (gdk_pixbuf_get_bits_per_sample(pixbuf) == 8); > + > + compressed_data = quic_encode_from_pixbuf(pixbuf); > + > + uncompressed_pixbuf = quic_decode_to_pixbuf(compressed_data); > + > + g_assert(gdk_pixbuf_get_byte_length(pixbuf) == > gdk_pixbuf_get_byte_length(uncompressed_pixbuf)); > + //g_assert(memcmp(gdk_pixbuf_get_pixels(pixbuf), > gdk_pixbuf_get_pixels(uncompressed_pixbuf), > gdk_pixbuf_get_byte_length(uncompressed_pixbuf))); > + gdk_pixbuf_compare(pixbuf, uncompressed_pixbuf); > + > + g_byte_array_free(compressed_data, TRUE); > + g_object_unref(uncompressed_pixbuf); > + > +} > + > +int main(int argc, char **argv) > +{ > + if (argc == 2) { > + GdkPixbuf *source_pixbuf; > + > + source_pixbuf = gdk_pixbuf_new_from_file(argv[1], NULL); > + test_pixbuf(source_pixbuf); > + g_object_unref(source_pixbuf); > + } else if (argc == 1) { > + unsigned int count; > + > + for (count = 0; count < 50; count++) { > + GdkPixbuf *pixbuf = gdk_pixbuf_new_random(); > + test_pixbuf(pixbuf); > + g_object_unref(pixbuf); > + } > + } else { > + g_assert_not_reached(); > + } > + > + return 0; > +} Frediano _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel