[Swfdec] Branch 'interpreter' - 15 commits - configure.ac libswfdec/swfdec_audio_event.c libswfdec/swfdec_button_movie.c libswfdec/swfdec_color.c libswfdec/swfdec_color.h libswfdec/swfdec_compiler.c libswfdec/swfdec_image.c libswfdec/swfdec_sprite_movie.c test/image test/Makefile.am test/sound

Benjamin Otte company at kemper.freedesktop.org
Tue Feb 6 05:59:21 PST 2007


 configure.ac                                   |    1 
 libswfdec/swfdec_audio_event.c                 |    1 
 libswfdec/swfdec_button_movie.c                |    3 
 libswfdec/swfdec_color.c                       |   26 ++
 libswfdec/swfdec_color.h                       |    2 
 libswfdec/swfdec_compiler.c                    |    5 
 libswfdec/swfdec_image.c                       |   26 --
 libswfdec/swfdec_sprite_movie.c                |    3 
 test/Makefile.am                               |    2 
 test/image/.gitignore                          |   11 +
 test/image/Makefile.am                         |   14 +
 test/image/color-transform-add80-alpha.swf     |binary
 test/image/color-transform-add80-alpha.swf.png |binary
 test/image/color-transform-add80.swf           |binary
 test/image/color-transform-add80.swf.png       |binary
 test/image/image-lossless-alpha.swf            |binary
 test/image/image-lossless-alpha.swf.png        |binary
 test/image/image.c                             |  243 +++++++++++++++++++++++++
 test/sound/sound.c                             |   20 +-
 19 files changed, 324 insertions(+), 33 deletions(-)

New commits:
diff-tree 375b6d4dc5d4335c3fcafa0ce96076287ae2b9ac (from parents)
Merge: a86c50354559053bfdba86f13cdf8ec9c455205a bdc67ff4e611ed187083eb9a45db630eecb260dd
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Feb 6 12:20:07 2007 +0100

    Merge branch 'master' into interpreter

diff --cc test/Makefile.am
index 33a647c,e0957af..00c8203
@@@ -1,10 -1,6 +1,10 @@@
- SUBDIRS = sound trace various
+ SUBDIRS = image sound trace various
  
 -noinst_PROGRAMS = swfdec-extract dump parse
 +if WITH_GTK
 +noinst_PROGRAMS = swfdec-extract dump parse swfedit
 +else
 +noinst_PROGRAMS = swfdec-extract dump parse 
 +endif
  
  dump_CFLAGS = $(GLOBAL_CFLAGS) $(SWF_CFLAGS) $(CAIRO_CFLAGS) $(PANGO_CFLAGS) -DXP_UNIX -I$(top_builddir)/libswfdec/js
  dump_LDFLAGS = $(SWF_LIBS) $(CAIRO_LIBS) $(PANGO_LIBS)
diff-tree bdc67ff4e611ed187083eb9a45db630eecb260dd (from af37862080c916e0792c5db1d3e298d6ea6fc7e7)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Feb 6 11:55:00 2007 +0100

    only unref result from _audio_event_new if there is something to unref

diff --git a/libswfdec/swfdec_button_movie.c b/libswfdec/swfdec_button_movie.c
index 92d40b9..e090c60 100644
--- a/libswfdec/swfdec_button_movie.c
+++ b/libswfdec/swfdec_button_movie.c
@@ -151,7 +151,8 @@ swfdec_button_movie_change_mouse (Swfdec
     audio = swfdec_audio_event_new (
 	SWFDEC_ROOT_MOVIE (SWFDEC_MOVIE (movie)->root)->player,
 	movie->button->sounds[sound]);
-    g_object_unref (audio);
+    if (audio)
+      g_object_unref (audio);
   }
   movie->mouse_in = mouse_in;
   movie->mouse_button = button;
diff --git a/libswfdec/swfdec_sprite_movie.c b/libswfdec/swfdec_sprite_movie.c
index f303f33..2ca5877 100644
--- a/libswfdec/swfdec_sprite_movie.c
+++ b/libswfdec/swfdec_sprite_movie.c
@@ -264,7 +264,8 @@ swfdec_sprite_movie_iterate_end (SwfdecM
   if (movie->sound_frame != movie->current_frame) {
     for (walk = current->sound; walk; walk = walk->next) {
       SwfdecAudio *audio = swfdec_audio_event_new (player, walk->data);
-      g_object_unref (audio);
+      if (audio)
+	g_object_unref (audio);
     }
   }
 
diff-tree af37862080c916e0792c5db1d3e298d6ea6fc7e7 (from f738d6e4e472166f379f5cb0962d96c8edfc49aa)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Feb 6 11:54:21 2007 +0100

    ref an audio event when reusing

diff --git a/libswfdec/swfdec_audio_event.c b/libswfdec/swfdec_audio_event.c
index 5895074..e0f05dc 100644
--- a/libswfdec/swfdec_audio_event.c
+++ b/libswfdec/swfdec_audio_event.c
@@ -132,6 +132,7 @@ swfdec_audio_event_new (SwfdecPlayer *pl
       (event = (SwfdecAudioEvent *) swfdec_audio_event_get (player, chunk->sound))) {
     SWFDEC_DEBUG ("sound %d is already playing, reusing it", 
 	SWFDEC_CHARACTER (chunk->sound)->id);
+    g_object_ref (event);
     return SWFDEC_AUDIO (event);
   }
   event = g_object_new (SWFDEC_TYPE_AUDIO_EVENT, NULL);
diff-tree f738d6e4e472166f379f5cb0962d96c8edfc49aa (from ab415fae5fab598414213d603bc97721840727b0)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Feb 6 11:53:54 2007 +0100

    list all failed tests at end of run

diff --git a/test/sound/sound.c b/test/sound/sound.c
index b74f9e2..f42149f 100644
--- a/test/sound/sound.c
+++ b/test/sound/sound.c
@@ -245,7 +245,7 @@ error:
 int
 main (int argc, char **argv)
 {
-  guint failed_tests = 0;
+  GList *failed_tests = NULL;
 
   swfdec_init ();
 
@@ -253,7 +253,7 @@ main (int argc, char **argv)
     int i;
     for (i = 1; i < argc; i++) {
       if (!run_test (argv[i]))
-	failed_tests++;
+	failed_tests = g_list_prepend (failed_tests, g_strdup (argv[i]));;
     }
   } else {
     GDir *dir;
@@ -263,16 +263,24 @@ main (int argc, char **argv)
       if (!g_str_has_suffix (file, ".swf"))
 	continue;
       if (!run_test (file))
-	failed_tests++;
+	failed_tests = g_list_prepend (failed_tests, g_strdup (file));
     }
     g_dir_close (dir);
   }
 
   if (failed_tests) {
-    g_print ("\nFAILURES: %u\n", failed_tests);
+    GList *walk;
+    failed_tests = g_list_sort (failed_tests, (GCompareFunc) strcmp);
+    g_print ("\nFAILURES: %u\n", g_list_length (failed_tests));
+    for (walk = failed_tests; walk; walk = walk->next) {
+      g_print ("          %s\n", (char *) walk->data);
+      g_free (walk->data);
+    }
+    g_list_free (failed_tests);
+    return 1;
   } else {
     g_print ("\nEVERYTHING OK\n");
+    return 0;
   }
-  return failed_tests;
 }
 
diff-tree ab415fae5fab598414213d603bc97721840727b0 (from 9cef35d65cdcba5be0c0bf9e395f00161a1cd37b)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Feb 6 11:53:08 2007 +0100

    fix failed test accumulation when using command line arguments

diff --git a/test/image/image.c b/test/image/image.c
index 5b5875f..85c00e1 100644
--- a/test/image/image.c
+++ b/test/image/image.c
@@ -210,7 +210,7 @@ main (int argc, char **argv)
     int i;
     for (i = 1; i < argc; i++) {
       if (!run_test (argv[i]))
-	failed_tests++;
+	failed_tests = g_list_prepend (failed_tests, g_strdup (argv[i]));
     }
   } else {
     GDir *dir;
diff-tree 9cef35d65cdcba5be0c0bf9e395f00161a1cd37b (from f8ad5602edb3223fcc0396a60d6077ad562be7e1)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Feb 6 10:05:45 2007 +0100

    DO COMPILE BEFORE CHECKING STUFF IN!
    
    sheesh

diff --git a/libswfdec/swfdec_image.c b/libswfdec/swfdec_image.c
index 4463228..fc0b1f1 100644
--- a/libswfdec/swfdec_image.c
+++ b/libswfdec/swfdec_image.c
@@ -657,7 +657,7 @@ swfdec_image_create_surface_transformed 
   for (i = 0; i < n; i++) {
     ((guint32 *) tdata)[i] = swfdec_color_apply_transform_premultiplied (((guint32 *) sdata)[i], trans);
     /* optimization: check for alpha channel to speed up compositing */
-    has_alpha != tdata[4 * i + SWFDEC_COLOR_INDEX_ALPHA] != 0xFF;
+    has_alpha = tdata[4 * i + SWFDEC_COLOR_INDEX_ALPHA] != 0xFF;
   }
   surface = cairo_image_surface_create_for_data (tdata,
       has_alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, 
diff-tree f8ad5602edb3223fcc0396a60d6077ad562be7e1 (from 7ee699c59898c37528d0051fd0c25f6756338dbe)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Feb 6 09:56:22 2007 +0100

    add first image tests

diff --git a/test/image/Makefile.am b/test/image/Makefile.am
index 7e46bee..3ba1485 100644
--- a/test/image/Makefile.am
+++ b/test/image/Makefile.am
@@ -5,3 +5,10 @@ image_SOURCES = image.c
 image_CFLAGS = $(GLOBAL_CFLAGS) $(SWF_CFLAGS) $(CAIRO_CFLAGS)
 image_LDFLAGS = $(SWF_LIBS) $(CAIRO_LIBS)
 
+EXTRA_DIST = \
+	color-transform-add80.swf \
+	color-transform-add80.swf.png \
+	color-transform-add80-alpha.swf \
+	color-transform-add80-alpha.swf.png \
+	image-lossless-alpha.swf \
+	image-lossless-alpha.swf.png
diff --git a/test/image/color-transform-add80-alpha.swf b/test/image/color-transform-add80-alpha.swf
new file mode 100755
index 0000000..841ba01
Binary files /dev/null and b/test/image/color-transform-add80-alpha.swf differ
diff --git a/test/image/color-transform-add80-alpha.swf.png b/test/image/color-transform-add80-alpha.swf.png
new file mode 100755
index 0000000..b927273
Binary files /dev/null and b/test/image/color-transform-add80-alpha.swf.png differ
diff --git a/test/image/color-transform-add80.swf b/test/image/color-transform-add80.swf
new file mode 100755
index 0000000..f692312
Binary files /dev/null and b/test/image/color-transform-add80.swf differ
diff --git a/test/image/color-transform-add80.swf.png b/test/image/color-transform-add80.swf.png
new file mode 100755
index 0000000..7ec2ef6
Binary files /dev/null and b/test/image/color-transform-add80.swf.png differ
diff --git a/test/image/image-lossless-alpha.swf b/test/image/image-lossless-alpha.swf
new file mode 100755
index 0000000..3ea6d69
Binary files /dev/null and b/test/image/image-lossless-alpha.swf differ
diff --git a/test/image/image-lossless-alpha.swf.png b/test/image/image-lossless-alpha.swf.png
new file mode 100755
index 0000000..d1689a7
Binary files /dev/null and b/test/image/image-lossless-alpha.swf.png differ
diff-tree 7ee699c59898c37528d0051fd0c25f6756338dbe (from 801292bafb7bb89ecae7a2764307fda87cb540f0)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Feb 6 09:53:20 2007 +0100

    make rendering more accurate
    
    - Don't premultiply images, they are already premultiplied
    - Use swfdec_color_apply_transform_premultiplied since the image is premultiplied

diff --git a/libswfdec/swfdec_image.c b/libswfdec/swfdec_image.c
index 224e101..4463228 100644
--- a/libswfdec/swfdec_image.c
+++ b/libswfdec/swfdec_image.c
@@ -588,24 +588,6 @@ swfdec_image_ensure_loaded (SwfdecImage 
   return TRUE;
 }
 
-static void
-swfdec_image_premultiply (guint8 *data, guint n)
-{
-  guint i;
-
-  for (i = 0; i < n; i++, data += 4) {
-    if (data[SWFDEC_COLOR_INDEX_ALPHA] == 0xFF)
-      continue;
-    if (data[SWFDEC_COLOR_INDEX_ALPHA] == 0) {
-      data[SWFDEC_COLOR_INDEX_RED] = data[SWFDEC_COLOR_INDEX_GREEN] = data[SWFDEC_COLOR_INDEX_BLUE] = 0;
-    } else {
-      data[SWFDEC_COLOR_INDEX_RED] = (guint) data[SWFDEC_COLOR_INDEX_RED] * data[SWFDEC_COLOR_INDEX_ALPHA] / 255;
-      data[SWFDEC_COLOR_INDEX_GREEN] = (guint) data[SWFDEC_COLOR_INDEX_GREEN] * data[SWFDEC_COLOR_INDEX_ALPHA] / 255;
-      data[SWFDEC_COLOR_INDEX_BLUE] = (guint) data[SWFDEC_COLOR_INDEX_BLUE] * data[SWFDEC_COLOR_INDEX_ALPHA] / 255;
-    }
-  }
-}
-
 static gboolean
 swfdec_image_has_alpha (SwfdecImage *image)
 {
@@ -635,7 +617,6 @@ swfdec_image_create_surface (SwfdecImage
     /* FIXME: only works if rowstride == image->width * 4 */
     data = cairo_image_surface_get_data (surface);
     memcpy (data, image->data, image->width * image->height * 4);
-    swfdec_image_premultiply (data, image->width * image->height);
     return surface;
   } else {
     image->surface = cairo_image_surface_create_for_data (image->data,
@@ -674,11 +655,10 @@ swfdec_image_create_surface_transformed 
   sdata = image->data;
   n = image->width * image->height;
   for (i = 0; i < n; i++) {
-    ((guint32 *) tdata)[i] = swfdec_color_apply_transform (((guint32 *) sdata)[i], trans);
-    has_alpha |= tdata[4 * i + SWFDEC_COLOR_INDEX_ALPHA] != 0xFF;
+    ((guint32 *) tdata)[i] = swfdec_color_apply_transform_premultiplied (((guint32 *) sdata)[i], trans);
+    /* optimization: check for alpha channel to speed up compositing */
+    has_alpha != tdata[4 * i + SWFDEC_COLOR_INDEX_ALPHA] != 0xFF;
   }
-  if (has_alpha)
-    swfdec_image_premultiply (tdata, n);
   surface = cairo_image_surface_create_for_data (tdata,
       has_alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, 
       image->width, image->height, image->width * 4);
diff-tree 801292bafb7bb89ecae7a2764307fda87cb540f0 (from 4f17e493901cc45e47302c4fc74e1f685a32755e)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Feb 6 09:50:42 2007 +0100

    add swfdec_color_apply_transform_premultiplied

diff --git a/libswfdec/swfdec_color.c b/libswfdec/swfdec_color.c
index 73276a0..ee3a63f 100644
--- a/libswfdec/swfdec_color.c
+++ b/libswfdec/swfdec_color.c
@@ -56,6 +56,32 @@ swfdec_color_set_source (cairo_t *cr, Sw
       SWFDEC_COLOR_B (color) / 255.0, SWFDEC_COLOR_A (color) / 255.0);
 }
 
+SwfdecColor
+swfdec_color_apply_transform_premultiplied (SwfdecColor in, 
+    const SwfdecColorTransform * trans)
+{
+  int r, g, b, a, aold;
+
+  aold = SWFDEC_COLOR_A (in);
+  if (aold == 0)
+    return 0;
+
+  a = (aold * trans->aa >> 8) + trans->ab;
+  a = CLAMP (a, 0, 255);
+
+  r = SWFDEC_COLOR_R (in);
+  g = SWFDEC_COLOR_G (in);
+  b = SWFDEC_COLOR_B (in);
+  r = (r * trans->ra * a / aold >> 8) + trans->rb * a / 255;
+  r = CLAMP (r, 0, a);
+  g = (g * trans->ga * a / aold >> 8) + trans->gb * a / 255;
+  g = CLAMP (g, 0, a);
+  b = (b * trans->ba * a / aold >> 8) + trans->bb * a / 255;
+  b = CLAMP (b, 0, a);
+
+  return SWFDEC_COLOR_COMBINE (r, g, b, a);
+}
+
 unsigned int
 swfdec_color_apply_transform (unsigned int in, const SwfdecColorTransform * trans)
 {
diff --git a/libswfdec/swfdec_color.h b/libswfdec/swfdec_color.h
index 46fdea4..54ce268 100644
--- a/libswfdec/swfdec_color.h
+++ b/libswfdec/swfdec_color.h
@@ -77,6 +77,8 @@ void swfdec_color_transform_chain (Swfde
     const SwfdecColorTransform *last, const SwfdecColorTransform *first);
 unsigned int swfdec_color_apply_transform (unsigned int in,
     const SwfdecColorTransform * trans);
+SwfdecColor swfdec_color_apply_transform_premultiplied (SwfdecColor in, 
+    const SwfdecColorTransform * trans);
 
 void swfdec_matrix_ensure_invertible (cairo_matrix_t *matrix, cairo_matrix_t *inverse);
 double swfdec_matrix_get_xscale (const cairo_matrix_t *matrix);
diff-tree 4f17e493901cc45e47302c4fc74e1f685a32755e (from 469f29442894cdea2116ac801501057266f28727)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Feb 6 09:50:11 2007 +0100

    Check action data is available before trying to compile action

diff --git a/libswfdec/swfdec_compiler.c b/libswfdec/swfdec_compiler.c
index 737a4d9..e7b39e3 100644
--- a/libswfdec/swfdec_compiler.c
+++ b/libswfdec/swfdec_compiler.c
@@ -1310,6 +1310,9 @@ swfdec_compile (SwfdecPlayer *player, Sw
     } else {
       len = 0;
     }
+    if (swfdec_bits_left (bits) < len * 8) {
+      compile_state_error (&state, "Not enough data available to parse next action");
+    }
 #ifndef G_DISABLE_ASSERT
     target = bits->ptr + len;
 #endif
diff-tree 469f29442894cdea2116ac801501057266f28727 (from 93148116d47fcaaa7bb894dd73f8c35b555289f0)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Feb 6 09:48:07 2007 +0100

    improve image test
    
    - list failed tests like trace.c
    - use imagediff (taken from cairo) to compare images
    - dump diff image in dump mode

diff --git a/test/image/image.c b/test/image/image.c
index 3200032..5b5875f 100644
--- a/test/image/image.c
+++ b/test/image/image.c
@@ -23,10 +23,67 @@
 #include <string.h>
 #include <libswfdec/swfdec.h>
 
+/* Compare two buffers, returning the number of pixels that are
+ * different and the maximum difference of any single color channel in
+ * result_ret.
+ *
+ * This function should be rewritten to compare all formats supported by
+ * cairo_format_t instead of taking a mask as a parameter.
+ */
+static gboolean
+buffer_diff_core (unsigned char *buf_a,
+		  unsigned char *buf_b,
+		  unsigned char *buf_diff,
+		  int		width,
+		  int		height,
+		  int		stride)
+{
+    int x, y;
+    gboolean result = TRUE;
+    guint32 *row_a, *row_b, *row;
+
+    for (y = 0; y < height; y++) {
+	row_a = (guint32 *) (buf_a + y * stride);
+	row_b = (guint32 *) (buf_b + y * stride);
+	row = (guint32 *) (buf_diff + y * stride);
+	for (x = 0; x < width; x++) {
+	    /* check if the pixels are the same */
+	    if (row_a[x] != row_b[x]) {
+		int channel;
+		static const unsigned int threshold = 3;
+		guint32 diff_pixel = 0;
+
+		/* calculate a difference value for all 4 channels */
+		for (channel = 0; channel < 4; channel++) {
+		    int value_a = (row_a[x] >> (channel*8)) & 0xff;
+		    int value_b = (row_b[x] >> (channel*8)) & 0xff;
+		    unsigned int diff;
+		    diff = ABS (value_a - value_b);
+		    if (diff <= threshold)
+		      continue;
+		    diff *= 4;  /* emphasize */
+		    diff += 128; /* make sure it's visible */
+		    if (diff > 255)
+		        diff = 255;
+		    diff_pixel |= diff << (channel*8);
+		}
+
+		row[x] = diff_pixel;
+		if (diff_pixel)
+		  result = FALSE;
+	    } else {
+		row[x] = 0;
+	    }
+	    row[x] |= 0xff000000; /* Set ALPHA to 100% (opaque) */
+	}
+    }
+    return result;
+}
+
 static gboolean
 image_diff (cairo_surface_t *surface, const char *filename)
 {
-  cairo_surface_t *image;
+  cairo_surface_t *image, *diff = NULL;
   int w, h;
   char *real;
 
@@ -49,28 +106,45 @@ image_diff (cairo_surface_t *surface, co
 	w, h);
     goto dump;
   }
+  diff = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h);
   g_assert (cairo_image_surface_get_stride (surface) == 4 * w);
   g_assert (cairo_image_surface_get_stride (image) == 4 * w);
-  if (memcmp (cairo_image_surface_get_data (surface), 
-	cairo_image_surface_get_data (image), 4 * w * h) != 0) {
+  g_assert (cairo_image_surface_get_stride (diff) == 4 * w);
+  if (!buffer_diff_core (cairo_image_surface_get_data (surface), 
+	cairo_image_surface_get_data (image), 
+	cairo_image_surface_get_data (diff), 
+	w, h, 4 * w) != 0) {
     g_print ("  ERROR: images differ\n");
     goto dump;
   }
 
   cairo_surface_destroy (image);
+  cairo_surface_destroy (diff);
   return TRUE;
 
 dump:
   cairo_surface_destroy (image);
   if (g_getenv ("SWFDEC_TEST_DUMP")) {
     cairo_status_t status;
-    char *dump = g_strdup_printf ("%s.dump.png", filename);
+    char *dump;
+    
+    dump = g_strdup_printf ("%s.dump.png", filename);
     status = cairo_surface_write_to_png (surface, dump);
     if (status) {
       g_print ("  ERROR: failed to dump image to %s: %s\n", dump,
 	  cairo_status_to_string (status));
     }
     g_free (dump);
+    if (diff) {
+      dump = g_strdup_printf ("%s.diff.png", filename);
+      status = cairo_surface_write_to_png (diff, dump);
+      if (status) {
+	g_print ("  ERROR: failed to dump diff image to %s: %s\n", dump,
+	    cairo_status_to_string (status));
+      }
+      g_free (dump);
+      cairo_surface_destroy (diff);
+    }
   }
   return FALSE;
 }
@@ -128,7 +202,7 @@ error:
 int
 main (int argc, char **argv)
 {
-  guint failed_tests = 0;
+  GList *failed_tests = NULL;
 
   swfdec_init ();
 
@@ -146,16 +220,24 @@ main (int argc, char **argv)
       if (!g_str_has_suffix (file, ".swf"))
 	continue;
       if (!run_test (file))
-	failed_tests++;
+	failed_tests = g_list_prepend (failed_tests, g_strdup (file));
     }
     g_dir_close (dir);
   }
 
   if (failed_tests) {
-    g_print ("\nFAILURES: %u\n", failed_tests);
+    GList *walk;
+    failed_tests = g_list_sort (failed_tests, (GCompareFunc) strcmp);
+    g_print ("\nFAILURES: %u\n", g_list_length (failed_tests));
+    for (walk = failed_tests; walk; walk = walk->next) {
+      g_print ("          %s\n", (char *) walk->data);
+      g_free (walk->data);
+    }
+    g_list_free (failed_tests);
+    return 1;
   } else {
     g_print ("\nEVERYTHING OK\n");
+    return 0;
   }
-  return failed_tests;
 }
 
diff-tree 93148116d47fcaaa7bb894dd73f8c35b555289f0 (from 42a9937af339fd582d83032e5bce71bc62b8aecf)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Feb 5 11:43:12 2007 +0100

    Add testing framework for drawing output

diff --git a/configure.ac b/configure.ac
index e02adfd..f0d0dbd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -185,6 +185,7 @@ libswfdec/jpeg/Makefile
 libswfdec/js/Makefile
 player/Makefile
 test/Makefile
+test/image/Makefile
 test/sound/Makefile
 test/trace/Makefile
 test/various/Makefile
diff --git a/test/Makefile.am b/test/Makefile.am
index 01c4f45..e0957af 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = sound trace various
+SUBDIRS = image sound trace various
 
 noinst_PROGRAMS = swfdec-extract dump parse
 
diff --git a/test/image/.gitignore b/test/image/.gitignore
new file mode 100644
index 0000000..5cb64c3
--- /dev/null
+++ b/test/image/.gitignore
@@ -0,0 +1,11 @@
+*~
+CVS
+.cvsignore
+.deps
+.libs
+
+Makefile
+Makefile.in
+*.o
+
+image
diff --git a/test/image/Makefile.am b/test/image/Makefile.am
new file mode 100644
index 0000000..7e46bee
--- /dev/null
+++ b/test/image/Makefile.am
@@ -0,0 +1,7 @@
+check_PROGRAMS = image
+TESTS = $(check_PROGRAMS)
+
+image_SOURCES = image.c
+image_CFLAGS = $(GLOBAL_CFLAGS) $(SWF_CFLAGS) $(CAIRO_CFLAGS)
+image_LDFLAGS = $(SWF_LIBS) $(CAIRO_LIBS)
+
diff --git a/test/image/image.c b/test/image/image.c
new file mode 100644
index 0000000..3200032
--- /dev/null
+++ b/test/image/image.c
@@ -0,0 +1,161 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <string.h>
+#include <libswfdec/swfdec.h>
+
+static gboolean
+image_diff (cairo_surface_t *surface, const char *filename)
+{
+  cairo_surface_t *image;
+  int w, h;
+  char *real;
+
+  real = g_strdup_printf ("%s.png", filename);
+  image = cairo_image_surface_create_from_png (real);
+  if (cairo_surface_status (image)) {
+    g_print ("  ERROR: Could not load %s: %s\n", real,
+	cairo_status_to_string (cairo_surface_status (image)));
+    g_free (real);
+    goto dump;
+  }
+  g_free (real);
+  g_assert (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_IMAGE);
+  w = cairo_image_surface_get_width (surface);
+  h = cairo_image_surface_get_height (surface);
+  if (w != cairo_image_surface_get_width (image) ||
+      h != cairo_image_surface_get_height (image)) {
+    g_print ("  ERROR: sizes don't match. Should be %ux%u, but is %ux%u\n",
+	cairo_image_surface_get_width (image), cairo_image_surface_get_height (image),
+	w, h);
+    goto dump;
+  }
+  g_assert (cairo_image_surface_get_stride (surface) == 4 * w);
+  g_assert (cairo_image_surface_get_stride (image) == 4 * w);
+  if (memcmp (cairo_image_surface_get_data (surface), 
+	cairo_image_surface_get_data (image), 4 * w * h) != 0) {
+    g_print ("  ERROR: images differ\n");
+    goto dump;
+  }
+
+  cairo_surface_destroy (image);
+  return TRUE;
+
+dump:
+  cairo_surface_destroy (image);
+  if (g_getenv ("SWFDEC_TEST_DUMP")) {
+    cairo_status_t status;
+    char *dump = g_strdup_printf ("%s.dump.png", filename);
+    status = cairo_surface_write_to_png (surface, dump);
+    if (status) {
+      g_print ("  ERROR: failed to dump image to %s: %s\n", dump,
+	  cairo_status_to_string (status));
+    }
+    g_free (dump);
+  }
+  return FALSE;
+}
+
+static gboolean
+run_test (const char *filename)
+{
+  SwfdecLoader *loader;
+  SwfdecPlayer *player = NULL;
+  guint i, msecs;
+  GError *error = NULL;
+  int w, h;
+  cairo_surface_t *surface;
+  cairo_t *cr;
+
+  g_print ("Testing %s:\n", filename);
+
+  loader = swfdec_loader_new_from_file (filename, &error);
+  if (loader == NULL) {
+    g_print ("  ERROR: %s\n", error->message);
+    goto error;
+  }
+  player = swfdec_player_new ();
+  swfdec_player_set_loader (player, loader);
+
+  for (i = 0; i < 10; i++) {
+    msecs = swfdec_player_get_next_event (player);
+    swfdec_player_advance (player, msecs);
+  }
+  swfdec_player_get_image_size (player, &w, &h);
+  if (w == 0 || h == 0) {
+    g_print ("  ERROR: width and height not set\n");
+    goto error;
+  }
+  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h);
+  cr = cairo_create (surface);
+  swfdec_player_render (player, cr, 0, 0, w, h); 
+  cairo_destroy (cr);
+  if (!image_diff (surface, filename)) {
+    cairo_surface_destroy (surface);
+    goto error;
+  }
+  cairo_surface_destroy (surface);
+  g_object_unref (player);
+  return TRUE;
+
+error:
+  if (error)
+    g_error_free (error);
+  if (player)
+    g_object_unref (player);
+  return FALSE;
+}
+
+int
+main (int argc, char **argv)
+{
+  guint failed_tests = 0;
+
+  swfdec_init ();
+
+  if (argc > 1) {
+    int i;
+    for (i = 1; i < argc; i++) {
+      if (!run_test (argv[i]))
+	failed_tests++;
+    }
+  } else {
+    GDir *dir;
+    const char *file;
+    dir = g_dir_open (".", 0, NULL);
+    while ((file = g_dir_read_name (dir))) {
+      if (!g_str_has_suffix (file, ".swf"))
+	continue;
+      if (!run_test (file))
+	failed_tests++;
+    }
+    g_dir_close (dir);
+  }
+
+  if (failed_tests) {
+    g_print ("\nFAILURES: %u\n", failed_tests);
+  } else {
+    g_print ("\nEVERYTHING OK\n");
+  }
+  return failed_tests;
+}
+
diff-tree 42a9937af339fd582d83032e5bce71bc62b8aecf (from c7ef38d8fd3cfabb9175bb7138f08dbd5b5e16bd)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Feb 5 11:39:25 2007 +0100

    Fix refcounting issue

diff --git a/test/sound/sound.c b/test/sound/sound.c
index 9b7ae58..b74f9e2 100644
--- a/test/sound/sound.c
+++ b/test/sound/sound.c
@@ -184,7 +184,6 @@ run_test (const char *filename)
   dir = g_dir_open (dirname, 0, &error);
   if (!dir) {
     g_print ("  ERROR: %s\n", error->message);
-    g_object_unref (player);
     return FALSE;
   }
   while ((name = g_dir_read_name (dir))) {
diff-tree c7ef38d8fd3cfabb9175bb7138f08dbd5b5e16bd (from 85de571784f502c8bd405eb3043ee079fd6a011c)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Feb 5 10:29:23 2007 +0100

    fix memleak

diff --git a/test/sound/sound.c b/test/sound/sound.c
index b9f54a3..9b7ae58 100644
--- a/test/sound/sound.c
+++ b/test/sound/sound.c
@@ -72,6 +72,7 @@ dump:
       g_print ("  ERROR: failed to dump contents: %s\n", error->message);
       g_error_free (error);
     }
+    g_free (dump);
   }
   return FALSE;
 }
diff-tree 85de571784f502c8bd405eb3043ee079fd6a011c (from d7db95f092791ed1e81ad2d2e4f9e3fb345d6f79)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Feb 4 18:50:46 2007 +0100

    that should be == NULL, not != NULL

diff --git a/libswfdec/swfdec_compiler.c b/libswfdec/swfdec_compiler.c
index 68221e3..737a4d9 100644
--- a/libswfdec/swfdec_compiler.c
+++ b/libswfdec/swfdec_compiler.c
@@ -559,7 +559,7 @@ compile_push (CompileState *state, guint
     switch (type) {
       case 0: /* string */
 	s = swfdec_bits_skip_string (state->bits);
-	if (s) {
+	if (s == NULL) {
 	  compile_state_error (state, "Push: Could not get string");
 	  return;
 	}


More information about the Swfdec mailing list