[Swfdec] 21 commits - configure.ac libswfdec/swfdec_audio_event.c libswfdec/swfdec_bits.c libswfdec/swfdec_button_movie.c libswfdec/swfdec_color.c libswfdec/swfdec_color.h libswfdec/swfdec_compiler.c libswfdec/swfdec_edittext.c libswfdec/swfdec_image.c libswfdec/swfdec_image.h libswfdec/swfdec_pattern.c libswfdec/swfdec_sprite.c libswfdec/swfdec_sprite_movie.c test/image test/Makefile.am test/sound test/swfdec-extract.c

Benjamin Otte company at kemper.freedesktop.org
Tue Feb 6 03:18:36 PST 2007


 configure.ac                                   |    1 
 libswfdec/swfdec_audio_event.c                 |    1 
 libswfdec/swfdec_bits.c                        |    4 
 libswfdec/swfdec_button_movie.c                |    3 
 libswfdec/swfdec_color.c                       |   67 +++++-
 libswfdec/swfdec_color.h                       |   31 ++-
 libswfdec/swfdec_compiler.c                    |    5 
 libswfdec/swfdec_edittext.c                    |    2 
 libswfdec/swfdec_image.c                       |  232 ++++++++++++-----------
 libswfdec/swfdec_image.h                       |    9 
 libswfdec/swfdec_pattern.c                     |   29 +-
 libswfdec/swfdec_sprite.c                      |    7 
 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 +-
 test/swfdec-extract.c                          |   14 +
 25 files changed, 526 insertions(+), 172 deletions(-)

New commits:
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;
 	}
diff-tree d7db95f092791ed1e81ad2d2e4f9e3fb345d6f79 (from ad56f27f4cc82a6913a7adcf05704b2cb91e6c61)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Feb 4 16:14:23 2007 +0100

    export images, too

diff --git a/test/swfdec-extract.c b/test/swfdec-extract.c
index bea068e..b4a2951 100644
--- a/test/swfdec-extract.c
+++ b/test/swfdec-extract.c
@@ -35,6 +35,7 @@
 #include <libswfdec/swfdec_audio_stream.h>
 #include <libswfdec/swfdec_button.h>
 #include <libswfdec/swfdec_graphic.h>
+#include <libswfdec/swfdec_image.h>
 #include <libswfdec/swfdec_player_internal.h>
 #include <libswfdec/swfdec_root_movie.h>
 #include <libswfdec/swfdec_sound.h>
@@ -206,6 +207,16 @@ export_graphic (SwfdecGraphic *graphic, 
   return surface_destroy_for_type (surface, filename);
 }
 
+static gboolean
+export_image (SwfdecImage *image, const char *filename)
+{
+  cairo_surface_t *surface = swfdec_image_create_surface (image);
+
+  if (surface == NULL)
+    return FALSE;
+  return surface_destroy_for_type (surface, filename);
+}
+
 static void
 usage (const char *app)
 {
@@ -258,6 +269,9 @@ main (int argc, char *argv[])
   } else if (SWFDEC_IS_GRAPHIC (character)) {
     if (!export_graphic (SWFDEC_GRAPHIC (character), argv[3]))
       ret = 1;
+  } else if (SWFDEC_IS_IMAGE (character)) {
+    if (!export_image (SWFDEC_IMAGE (character), argv[3]))
+      ret = 1;
   } else {
     g_printerr ("id %ld does not specify an exportable object", id);
     ret = 1;
diff-tree ad56f27f4cc82a6913a7adcf05704b2cb91e6c61 (from 32e4b86c8fac7b199a4f2d210f0ec6d67347091c)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Feb 4 16:14:13 2007 +0100

    add debugging message when parsing color transforms

diff --git a/libswfdec/swfdec_sprite.c b/libswfdec/swfdec_sprite.c
index 074bb37..246776a 100644
--- a/libswfdec/swfdec_sprite.c
+++ b/libswfdec/swfdec_sprite.c
@@ -364,6 +364,11 @@ swfdec_spriteseg_place_object_2 (SwfdecS
   }
   if (has_color_transform) {
     swfdec_bits_get_color_transform (bits, &content->color_transform);
+    SWFDEC_LOG ("  color transform = %d %d  %d %d  %d %d  %d %d",
+	content->color_transform.ra, content->color_transform.rb,
+	content->color_transform.ga, content->color_transform.gb,
+	content->color_transform.ba, content->color_transform.bb,
+	content->color_transform.aa, content->color_transform.ab);
   }
   swfdec_bits_syncbits (bits);
   if (has_ratio) {
diff-tree 32e4b86c8fac7b199a4f2d210f0ec6d67347091c (from 2399ad61b0ffc8fcbd1c395dc841deec152e29e4)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Feb 4 14:53:42 2007 +0100

    rename swfdec_image_get_surface* to swfdec_image_create_surface*
    
    - The renamed functions give out a reference to the surface now.
    - Ensure that surfaces created by those functions get unreffed properly
    - Add an obvious optimization by not applying the color transform if the
      transform is the identity transform

diff --git a/libswfdec/swfdec_image.c b/libswfdec/swfdec_image.c
index e276508..224e101 100644
--- a/libswfdec/swfdec_image.c
+++ b/libswfdec/swfdec_image.c
@@ -647,7 +647,7 @@ swfdec_image_create_surface (SwfdecImage
 }
 
 cairo_surface_t *
-swfdec_image_get_surface_transformed (SwfdecImage *image, const SwfdecColorTransform *trans)
+swfdec_image_create_surface_transformed (SwfdecImage *image, const SwfdecColorTransform *trans)
 {
   static const cairo_user_data_key_t key;
   cairo_surface_t *surface;
@@ -659,6 +659,10 @@ swfdec_image_get_surface_transformed (Sw
   g_return_val_if_fail (SWFDEC_IS_IMAGE (image), NULL);
   g_return_val_if_fail (trans != NULL, NULL);
 
+  /* obvious optimization */
+  if (swfdec_color_transform_is_identity (trans))
+    return swfdec_image_create_surface (image);
+
   if (!swfdec_image_ensure_loaded (image))
     return NULL;
 
diff --git a/libswfdec/swfdec_image.h b/libswfdec/swfdec_image.h
index ad40181..3c1e71e 100644
--- a/libswfdec/swfdec_image.h
+++ b/libswfdec/swfdec_image.h
@@ -66,8 +66,8 @@ struct _SwfdecImageClass {
 
 GType			swfdec_image_get_type		(void);
 
-cairo_surface_t *	swfdec_image_get_surface	(SwfdecImage *		image);
-cairo_surface_t *	swfdec_image_get_surface_transformed 
+cairo_surface_t *	swfdec_image_create_surface	(SwfdecImage *		image);
+cairo_surface_t *	swfdec_image_create_surface_transformed 
 							(SwfdecImage *		image,
 							 const SwfdecColorTransform *trans);
 
diff --git a/libswfdec/swfdec_pattern.c b/libswfdec/swfdec_pattern.c
index 938f827..536698a 100644
--- a/libswfdec/swfdec_pattern.c
+++ b/libswfdec/swfdec_pattern.c
@@ -266,9 +266,10 @@ swfdec_image_pattern_paint (SwfdecPatter
   cairo_matrix_t mat;
   cairo_surface_t *surface;
   
-  surface = swfdec_image_get_surface_transformed (image->image, trans);
+  surface = swfdec_image_create_surface_transformed (image->image, trans);
   cairo_append_path (cr, (cairo_path_t *) path);
   pattern = cairo_pattern_create_for_surface (surface);
+  cairo_surface_destroy (surface);
   swfdec_matrix_morph (&mat, &pat->start_transform, &pat->end_transform, ratio);
   cairo_pattern_set_matrix (pattern, &mat);
   cairo_pattern_set_extend (pattern, image->extend);
@@ -626,7 +627,7 @@ swfdec_pattern_to_string (SwfdecPattern 
   if (SWFDEC_IS_IMAGE_PATTERN (pattern)) {
     SwfdecImagePattern *image = SWFDEC_IMAGE_PATTERN (pattern);
     if (image->image->width == 0)
-      swfdec_image_get_surface (image->image);
+      cairo_surface_destroy (swfdec_image_create_surface (image->image));
     return g_strdup_printf ("%ux%u image %u (%s, %s)", image->image->width,
 	image->image->height, SWFDEC_CHARACTER (image->image)->id,
 	image->extend == CAIRO_EXTEND_REPEAT ? "repeat" : "no repeat",
diff-tree 2399ad61b0ffc8fcbd1c395dc841deec152e29e4 (from 180879c4af107625b53f37ba8bcc990eb20baf8b)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Feb 4 14:49:54 2007 +0100

    add swfdec_color_transform_is_identity
    
    useful for optimizations

diff --git a/libswfdec/swfdec_color.c b/libswfdec/swfdec_color.c
index 7761653..73276a0 100644
--- a/libswfdec/swfdec_color.c
+++ b/libswfdec/swfdec_color.c
@@ -1,7 +1,7 @@
 /* Swfdec
  * Copyright (C) 2003-2006 David Schleef <ds at schleef.org>
  *		 2005-2006 Eric Anholt <eric at anholt.net>
- *		      2006 Benjamin Otte <otte at gnome.org>
+ *		 2006-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
@@ -125,6 +125,13 @@ swfdec_color_transform_init_color (Swfde
   trans->ab = SWFDEC_COLOR_A (color);
 }
 
+gboolean
+swfdec_color_transform_is_identity (const SwfdecColorTransform * trans)
+{
+  return trans->ra == 256 && trans->ga == 256 && trans->ba == 256 && trans->aa == 256 &&
+      trans->rb == 0 && trans->gb == 0 && trans->bb == 0 && trans->ab == 0;
+}
+
 /**
  * swfdec_color_transform_chain:
  * @dest: #SwfdecColorTransform to take the result
diff --git a/libswfdec/swfdec_color.h b/libswfdec/swfdec_color.h
index b38c269..46fdea4 100644
--- a/libswfdec/swfdec_color.h
+++ b/libswfdec/swfdec_color.h
@@ -72,6 +72,7 @@ SwfdecColor swfdec_color_apply_morph (Sw
 void swfdec_color_set_source (cairo_t *cr, SwfdecColor color);
 void swfdec_color_transform_init_identity (SwfdecColorTransform * trans);
 void swfdec_color_transform_init_color (SwfdecColorTransform *trans, SwfdecColor color);
+gboolean swfdec_color_transform_is_identity (const SwfdecColorTransform * trans);
 void swfdec_color_transform_chain (SwfdecColorTransform *dest,
     const SwfdecColorTransform *last, const SwfdecColorTransform *first);
 unsigned int swfdec_color_apply_transform (unsigned int in,
diff-tree 180879c4af107625b53f37ba8bcc990eb20baf8b (from fa335acfbd3526f57dfb66c68e59334a79d90901)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Feb 4 14:33:59 2007 +0100

    rework images to be correctly color transformed
    
    - use new SWFDEC_COLOR_INDEX variables when decoding - avoids #if
    - ditch caching as we might need the unpremultiplied image for color transforms
    - implement swfdec_image_get_surface_transformed
    - use it in the image pattern

diff --git a/libswfdec/swfdec_image.c b/libswfdec/swfdec_image.c
index 0cf6502..e276508 100644
--- a/libswfdec/swfdec_image.c
+++ b/libswfdec/swfdec_image.c
@@ -50,7 +50,10 @@ swfdec_image_unload (SwfdecCached *cache
   if (image->surface) {
     cairo_surface_destroy (image->surface);
     image->surface = NULL;
+  } else if (image->data) {
+    g_free (image->data);
   }
+  image->data = NULL;
 }
 
 static void
@@ -185,24 +188,9 @@ tag_func_define_bits_jpeg (SwfdecSwfDeco
 }
 
 static void
-swfdec_image_create_surface (SwfdecImage *image, guint8 *data, gboolean has_alpha)
-{
-  static const cairo_user_data_key_t key;
-
-  g_assert (image->surface == NULL);
-
-  image->surface = cairo_image_surface_create_for_data (data,
-      has_alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, 
-      image->width, image->height, image->rowstride);
-  cairo_surface_set_user_data (image->surface, &key, data,
-      g_free);
-}
-
-static void
 swfdec_image_jpeg_load (SwfdecImage *image)
 {
   JpegRGBDecoder *dec;
-  unsigned char *image_data;
 
   dec = jpeg_rgb_decoder_new ();
 
@@ -217,10 +205,9 @@ swfdec_image_jpeg_load (SwfdecImage *ima
     return;
   }
   swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height);
-  jpeg_rgb_decoder_get_image (dec, &image_data,
+  jpeg_rgb_decoder_get_image (dec, &image->data,
       &image->rowstride, NULL, NULL);
   jpeg_rgb_decoder_free (dec);
-  swfdec_image_create_surface (image, image_data, FALSE);
 
   SWFDEC_LOG ("  width = %d", image->width);
   SWFDEC_LOG ("  height = %d", image->height);
@@ -252,7 +239,6 @@ static void
 swfdec_image_jpeg2_load (SwfdecImage *image)
 {
   JpegRGBDecoder *dec;
-  unsigned char *image_data;
 
   dec = jpeg_rgb_decoder_new ();
 
@@ -265,10 +251,9 @@ swfdec_image_jpeg2_load (SwfdecImage *im
     return;
   }
   swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height);
-  jpeg_rgb_decoder_get_image (dec, &image_data,
+  jpeg_rgb_decoder_get_image (dec, &image->data,
       &image->rowstride, &image->width, &image->height);
   jpeg_rgb_decoder_free (dec);
-  swfdec_image_create_surface (image, image_data, FALSE);
 
   SWFDEC_LOG ("  width = %d", image->width);
   SWFDEC_LOG ("  height = %d", image->height);
@@ -303,7 +288,6 @@ static void
 swfdec_image_jpeg3_load (SwfdecImage *image)
 {
   JpegRGBDecoder *dec;
-  unsigned char *image_data;
   unsigned char *alpha_data;
   SwfdecBits bits;
   int len;
@@ -328,7 +312,7 @@ swfdec_image_jpeg3_load (SwfdecImage *im
     return;
   }
   swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height);
-  jpeg_rgb_decoder_get_image (dec, &image_data,
+  jpeg_rgb_decoder_get_image (dec, &image->data,
       &image->rowstride, &image->width, &image->height);
   jpeg_rgb_decoder_free (dec);
 
@@ -336,11 +320,9 @@ swfdec_image_jpeg3_load (SwfdecImage *im
 
   alpha_data = lossless (bits.ptr, bits.end - bits.ptr, &len);
 
-  merge_alpha (image, image_data, alpha_data);
+  merge_alpha (image, image->data, alpha_data);
   g_free (alpha_data);
 
-  swfdec_image_create_surface (image, image_data, TRUE);
-
   SWFDEC_LOG ("  width = %d", image->width);
   SWFDEC_LOG ("  height = %d", image->height);
 }
@@ -355,11 +337,7 @@ merge_alpha (SwfdecImage * image, unsign
   for (y = 0; y < image->height; y++) {
     p = image_data + y * image->rowstride;
     for (x = 0; x < image->width; x++) {
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
-      p[3] = *alpha;
-#else
-      p[0] = *alpha;
-#endif
+      p[SWFDEC_COLOR_INDEX_ALPHA] = *alpha;
       p += 4;
       alpha++;
     }
@@ -375,7 +353,6 @@ swfdec_image_lossless_load (SwfdecImage 
   int len;
   unsigned char *endptr;
   SwfdecBits bits;
-  unsigned char *image_data = NULL;
   int have_alpha = (image->type == SWFDEC_IMAGE_TYPE_LOSSLESS2);
 
   bits.buffer = image->raw_data;
@@ -414,7 +391,7 @@ swfdec_image_lossless_load (SwfdecImage 
     unsigned char *indexed_data;
     int i;
 
-    image_data = g_malloc (4 * image->width * image->height);
+    image->data = g_malloc (4 * image->width * image->height);
     image->rowstride = image->width * 4;
 
     color_table = g_malloc (color_table_size * 4);
@@ -450,7 +427,7 @@ swfdec_image_lossless_load (SwfdecImage 
       }
       indexed_data = ptr + color_table_size * 3;
     }
-    swfdec_image_colormap_decode (image, image_data, indexed_data,
+    swfdec_image_colormap_decode (image, image->data, indexed_data,
 	color_table, color_table_size);
 
     g_free (color_table);
@@ -467,25 +444,18 @@ swfdec_image_lossless_load (SwfdecImage 
       have_alpha = FALSE;
     }
 
-    image_data = g_malloc (4 * image->width * image->height);
-    idata = image_data;
+    image->data = g_malloc (4 * image->width * image->height);
+    idata = image->data;
     image->rowstride = image->width * 4;
 
     /* 15 bit packed */
     for (j = 0; j < image->height; j++) {
       for (i = 0; i < image->width; i++) {
         c = p[1] | (p[0] << 8);
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
-        idata[0] = (c << 3) | ((c >> 2) & 0x7);
-        idata[1] = ((c >> 2) & 0xf8) | ((c >> 7) & 0x7);
-        idata[2] = ((c >> 7) & 0xf8) | ((c >> 12) & 0x7);
-        idata[3] = 0xff;
-#else
-        idata[3] = (c << 3) | ((c >> 2) & 0x7);
-        idata[2] = ((c >> 2) & 0xf8) | ((c >> 7) & 0x7);
-        idata[1] = ((c >> 7) & 0xf8) | ((c >> 12) & 0x7);
-        idata[0] = 0xff;
-#endif
+        idata[SWFDEC_COLOR_INDEX_BLUE] = (c << 3) | ((c >> 2) & 0x7);
+        idata[SWFDEC_COLOR_INDEX_GREEN] = ((c >> 2) & 0xf8) | ((c >> 7) & 0x7);
+        idata[SWFDEC_COLOR_INDEX_RED] = ((c >> 7) & 0xf8) | ((c >> 12) & 0x7);
+        idata[SWFDEC_COLOR_INDEX_ALPHA] = 0xff;
         p += 2;
         idata += 4;
       }
@@ -495,26 +465,17 @@ swfdec_image_lossless_load (SwfdecImage 
   if (format == 5) {
     int i, j;
 
-    image_data = ptr;
+    image->data = ptr;
     image->rowstride = image->width * 4;
 
-    if (!have_alpha) {
-      /* image is stored in 0RGB format.  We use ARGB/BGRA. */
-      for (j = 0; j < image->height; j++) {
-        for (i = 0; i < image->width; i++) {
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
-          ptr[0] = ptr[3];
-          ptr[1] = ptr[2];
-          ptr[2] = ptr[1];
-          ptr[3] = 255;
-#endif
-          ptr += 4;
-        }
+    /* image is stored in 0RGB format.  We use ARGB/BGRA. */
+    for (j = 0; j < image->height; j++) {
+      for (i = 0; i < image->width; i++) {
+	*((guint32 *) ptr) = GUINT32_FROM_BE (*((guint32 *) ptr));
+	ptr += 4;
       }
     }
   }
-
-  swfdec_image_create_surface (image, image_data, have_alpha);
 }
 
 int
@@ -592,68 +553,131 @@ swfdec_image_colormap_decode (SwfdecImag
   }
 }
 
+static gboolean
+swfdec_image_ensure_loaded (SwfdecImage *image)
+{
+  if (image->data == NULL) {
+    switch (image->type) {
+      case SWFDEC_IMAGE_TYPE_JPEG:
+	swfdec_image_jpeg_load (image);
+	break;
+      case SWFDEC_IMAGE_TYPE_JPEG2:
+	swfdec_image_jpeg2_load (image);
+	break;
+      case SWFDEC_IMAGE_TYPE_JPEG3:
+	swfdec_image_jpeg3_load (image);
+	break;
+      case SWFDEC_IMAGE_TYPE_LOSSLESS:
+	swfdec_image_lossless_load (image);
+	break;
+      case SWFDEC_IMAGE_TYPE_LOSSLESS2:
+	swfdec_image_lossless_load (image);
+	break;
+      case SWFDEC_IMAGE_TYPE_UNKNOWN:
+      default:
+	g_assert_not_reached ();
+	break;
+    }
+    if (image->data == NULL) {
+      SWFDEC_WARNING ("failed to load image data");
+      return FALSE;
+    }
+  } else {
+    swfdec_cached_use (SWFDEC_CACHED (image));
+  }
+  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)
+{
+  return image->type == SWFDEC_IMAGE_TYPE_LOSSLESS2 ||
+      image->type == SWFDEC_IMAGE_TYPE_JPEG3;
+}
+
 cairo_surface_t *
-swfdec_image_get_surface (SwfdecImage *image)
+swfdec_image_create_surface (SwfdecImage *image)
 {
+  static const cairo_user_data_key_t key;
+
   g_return_val_if_fail (SWFDEC_IS_IMAGE (image), NULL);
 
+  if (!swfdec_image_ensure_loaded (image))
+    return NULL;
   if (image->surface) {
-    swfdec_cached_use (SWFDEC_CACHED (image));
+    cairo_surface_reference (image->surface);
     return image->surface;
   }
 
-  switch (image->type) {
-    case SWFDEC_IMAGE_TYPE_JPEG:
-      swfdec_image_jpeg_load (image);
-      break;
-    case SWFDEC_IMAGE_TYPE_JPEG2:
-      swfdec_image_jpeg2_load (image);
-      break;
-    case SWFDEC_IMAGE_TYPE_JPEG3:
-      swfdec_image_jpeg3_load (image);
-      break;
-    case SWFDEC_IMAGE_TYPE_LOSSLESS:
-      swfdec_image_lossless_load (image);
-      break;
-    case SWFDEC_IMAGE_TYPE_LOSSLESS2:
-      swfdec_image_lossless_load (image);
-      break;
-    case SWFDEC_IMAGE_TYPE_UNKNOWN:
-    default:
-      g_assert_not_reached ();
-      break;
+  if (swfdec_image_has_alpha (image)) {
+    cairo_surface_t *surface;
+    guint8 *data;
+    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 
+	image->width, image->height);
+    /* 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,
+	CAIRO_FORMAT_RGB24, image->width, image->height, image->rowstride);
+    cairo_surface_set_user_data (image->surface, &key, image->data, g_free);
+    cairo_surface_reference (image->surface);
+    return image->surface;
   }
-
-  return image->surface;
 }
 
 cairo_surface_t *
-swfdec_image_get_surface_for_target (SwfdecImage *image, cairo_surface_t *target)
+swfdec_image_get_surface_transformed (SwfdecImage *image, const SwfdecColorTransform *trans)
 {
-  cairo_surface_t *current, *similar;
-  cairo_t *copy;
-  cairo_content_t content;
-
-  current = swfdec_image_get_surface (image);
-  if (cairo_surface_get_type (current) == cairo_surface_get_type (target))
-    return current;
-
-  /* FIXME: we might want to create multiple surfaces here if there's multiple
-   * live rendering sources. Right now, this is the quick fix, that transforms
-   * the cache to the most recent used type */
-  if (cairo_surface_get_type (current) == CAIRO_SURFACE_TYPE_IMAGE &&
-      cairo_image_surface_get_format (current) == CAIRO_FORMAT_RGB24)
-    content = CAIRO_CONTENT_COLOR;
-  else
-    content = CAIRO_CONTENT_COLOR_ALPHA;
-  similar = cairo_surface_create_similar (target,
-      content,
-      image->width, image->height);
-  copy = cairo_create (similar);
-  cairo_set_source_surface (copy, current, 0, 0);
-  cairo_paint (copy);
-  cairo_destroy (copy);
-  cairo_surface_destroy (current);
-  image->surface = similar;
-  return similar;
+  static const cairo_user_data_key_t key;
+  cairo_surface_t *surface;
+  guint8 *tdata;
+  const guint8 *sdata;
+  guint i, n;
+  gboolean has_alpha = FALSE;
+
+  g_return_val_if_fail (SWFDEC_IS_IMAGE (image), NULL);
+  g_return_val_if_fail (trans != NULL, NULL);
+
+  if (!swfdec_image_ensure_loaded (image))
+    return NULL;
+
+  tdata = g_try_malloc (image->width * image->height * 4);
+  if (!tdata) {
+    SWFDEC_ERROR ("failed to allocate memory for transformed image");
+    return NULL;
+  }
+  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;
+  }
+  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);
+  cairo_surface_set_user_data (surface, &key, tdata, g_free);
+  return surface;
 }
diff --git a/libswfdec/swfdec_image.h b/libswfdec/swfdec_image.h
index bcd22f0..ad40181 100644
--- a/libswfdec/swfdec_image.h
+++ b/libswfdec/swfdec_image.h
@@ -48,10 +48,11 @@ typedef enum {
 struct _SwfdecImage {
   SwfdecCached		cached;
 
-  cairo_surface_t *	surface;	/* surface that is on-demand loaded */
+  guint8 *		data;		/* image data in CAIRO_FORMAT_ARGB32 but NOT premultiplied */	
   int			width;
   int			height;
   int			rowstride;
+  cairo_surface_t *	surface;	/* surface that owns the data pointer or NULL (doesn't always work) */
 
   SwfdecImageType	type;
   SwfdecBuffer *	jpegtables;
@@ -66,9 +67,9 @@ struct _SwfdecImageClass {
 GType			swfdec_image_get_type		(void);
 
 cairo_surface_t *	swfdec_image_get_surface	(SwfdecImage *		image);
-cairo_surface_t *	swfdec_image_get_surface_for_target 
+cairo_surface_t *	swfdec_image_get_surface_transformed 
 							(SwfdecImage *		image,
-							 cairo_surface_t *	target);
+							 const SwfdecColorTransform *trans);
 
 int swfdec_image_jpegtables (SwfdecSwfDecoder * s);
 int tag_func_define_bits_jpeg (SwfdecSwfDecoder * s);
diff --git a/libswfdec/swfdec_pattern.c b/libswfdec/swfdec_pattern.c
index 2a614b0..938f827 100644
--- a/libswfdec/swfdec_pattern.c
+++ b/libswfdec/swfdec_pattern.c
@@ -263,14 +263,11 @@ swfdec_image_pattern_paint (SwfdecPatter
 {
   SwfdecImagePattern *image = SWFDEC_IMAGE_PATTERN (pat);
   cairo_pattern_t *pattern;
-  SwfdecColor color;
   cairo_matrix_t mat;
   cairo_surface_t *surface;
   
-  surface = swfdec_image_get_surface_for_target (image->image, 
-      cairo_get_target (cr));
+  surface = swfdec_image_get_surface_transformed (image->image, trans);
   cairo_append_path (cr, (cairo_path_t *) path);
-  color = swfdec_color_apply_transform (0xFFFFFFFF, trans);
   pattern = cairo_pattern_create_for_surface (surface);
   swfdec_matrix_morph (&mat, &pat->start_transform, &pat->end_transform, ratio);
   cairo_pattern_set_matrix (pattern, &mat);
@@ -278,14 +275,7 @@ swfdec_image_pattern_paint (SwfdecPatter
   cairo_pattern_set_filter (pattern, image->filter);
   cairo_set_source (cr, pattern);
   cairo_pattern_destroy (pattern);
-  if (SWFDEC_COLOR_A (color) < 255) {
-    cairo_save (cr);
-    cairo_clip (cr);
-    cairo_paint_with_alpha (cr, SWFDEC_COLOR_A (color) / 255.);
-    cairo_restore (cr);
-  } else {
-    cairo_fill (cr);
-  }
+  cairo_fill (cr);
 }
 
 static void
diff-tree fa335acfbd3526f57dfb66c68e59334a79d90901 (from 251f13c696e0c8c8eb10534d0ed9407d7fd26d19)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Feb 4 14:29:48 2007 +0100

    update SwfdecColor format from RGBA to ARGB
    
    This makes SwfdecColor match a pixel in an image in CAIRO_FORMAT_ARGB32

diff --git a/libswfdec/swfdec_color.h b/libswfdec/swfdec_color.h
index 07870c3..b38c269 100644
--- a/libswfdec/swfdec_color.h
+++ b/libswfdec/swfdec_color.h
@@ -1,7 +1,7 @@
 /* Swfdec
  * Copyright (C) 2003-2006 David Schleef <ds at schleef.org>
  *		 2005-2006 Eric Anholt <eric at anholt.net>
- *		      2006 Benjamin Otte <otte at gnome.org>
+ *		 2006-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
@@ -24,6 +24,8 @@
 
 #include <libswfdec/swfdec_types.h>
 
+/* Pixel value in the same colorspace as cairo - endian-dependant ARGB.
+ * The alpha pixel must be present */
 typedef unsigned int SwfdecColor;
 
 struct _SwfdecColorTransform {
@@ -46,11 +48,25 @@ struct swfdec_gradient_struct
   SwfdecGradientEntry array[1];
 };
 
-#define SWFDEC_COLOR_COMBINE(r,g,b,a)	(((r)<<24) | ((g)<<16) | ((b)<<8) | (a))
-#define SWFDEC_COLOR_R(x)		(((x)>>24)&0xff)
-#define SWFDEC_COLOR_G(x)		(((x)>>16)&0xff)
-#define SWFDEC_COLOR_B(x)		(((x)>>8)&0xff)
-#define SWFDEC_COLOR_A(x)		((x)&0xff)
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+#define SWFDEC_COLOR_INDEX_ALPHA (3)
+#define SWFDEC_COLOR_INDEX_RED (2)
+#define SWFDEC_COLOR_INDEX_GREEN (1)
+#define SWFDEC_COLOR_INDEX_BLUE (0)
+#elif G_BYTE_ORDER == G_BIG_ENDIAN
+#define SWFDEC_COLOR_INDEX_ALPHA (0)
+#define SWFDEC_COLOR_INDEX_RED (1)
+#define SWFDEC_COLOR_INDEX_GREEN (2)
+#define SWFDEC_COLOR_INDEX_BLUE (3)
+#else
+#error "Unknown byte order"
+#endif
+
+#define SWFDEC_COLOR_COMBINE(r,g,b,a)	(((a)<<24) | ((r)<<16) | ((g)<<8) | (b))
+#define SWFDEC_COLOR_A(x)		(((x)>>24)&0xff)
+#define SWFDEC_COLOR_R(x)		(((x)>>16)&0xff)
+#define SWFDEC_COLOR_G(x)		(((x)>>8)&0xff)
+#define SWFDEC_COLOR_B(x)		((x)&0xff)
 
 SwfdecColor swfdec_color_apply_morph (SwfdecColor start, SwfdecColor end, unsigned int ratio);
 void swfdec_color_set_source (cairo_t *cr, SwfdecColor color);
diff-tree 251f13c696e0c8c8eb10534d0ed9407d7fd26d19 (from 12bf86eb10e873ca735fad310d7ab9e517f6662b)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Feb 4 13:07:18 2007 +0100

    s/SWF_COLOR/SWFDEC_COLOR/
    
    fight wrong prefixes!

diff --git a/libswfdec/swfdec_bits.c b/libswfdec/swfdec_bits.c
index fb18394..5013e49 100644
--- a/libswfdec/swfdec_bits.c
+++ b/libswfdec/swfdec_bits.c
@@ -450,7 +450,7 @@ swfdec_bits_get_color (SwfdecBits * bits
   g = swfdec_bits_get_u8 (bits);
   b = swfdec_bits_get_u8 (bits);
 
-  return SWF_COLOR_COMBINE (r, g, b, 0xff);
+  return SWFDEC_COLOR_COMBINE (r, g, b, 0xff);
 }
 
 unsigned int
@@ -463,7 +463,7 @@ swfdec_bits_get_rgba (SwfdecBits * bits)
   b = swfdec_bits_get_u8 (bits);
   a = swfdec_bits_get_u8 (bits);
 
-  return SWF_COLOR_COMBINE (r, g, b, a);
+  return SWFDEC_COLOR_COMBINE (r, g, b, a);
 }
 
 SwfdecGradient *
diff --git a/libswfdec/swfdec_color.c b/libswfdec/swfdec_color.c
index 0d8a8be..7761653 100644
--- a/libswfdec/swfdec_color.c
+++ b/libswfdec/swfdec_color.c
@@ -40,20 +40,20 @@ swfdec_color_apply_morph (SwfdecColor st
     return end;
   start_ratio = 65535 - ratio;
   end_ratio = ratio;
-  r = (SWF_COLOR_R (start) * start_ratio + SWF_COLOR_R (end) * end_ratio) / 65535;
-  g = (SWF_COLOR_G (start) * start_ratio + SWF_COLOR_G (end) * end_ratio) / 65535;
-  b = (SWF_COLOR_B (start) * start_ratio + SWF_COLOR_B (end) * end_ratio) / 65535;
-  a = (SWF_COLOR_A (start) * start_ratio + SWF_COLOR_A (end) * end_ratio) / 65535;
+  r = (SWFDEC_COLOR_R (start) * start_ratio + SWFDEC_COLOR_R (end) * end_ratio) / 65535;
+  g = (SWFDEC_COLOR_G (start) * start_ratio + SWFDEC_COLOR_G (end) * end_ratio) / 65535;
+  b = (SWFDEC_COLOR_B (start) * start_ratio + SWFDEC_COLOR_B (end) * end_ratio) / 65535;
+  a = (SWFDEC_COLOR_A (start) * start_ratio + SWFDEC_COLOR_A (end) * end_ratio) / 65535;
 
-  return SWF_COLOR_COMBINE (r, g, b, a);
+  return SWFDEC_COLOR_COMBINE (r, g, b, a);
 }
 
 void 
 swfdec_color_set_source (cairo_t *cr, SwfdecColor color)
 {
   cairo_set_source_rgba (cr, 
-      SWF_COLOR_R (color) / 255.0, SWF_COLOR_G (color) / 255.0,
-      SWF_COLOR_B (color) / 255.0, SWF_COLOR_A (color) / 255.0);
+      SWFDEC_COLOR_R (color) / 255.0, SWFDEC_COLOR_G (color) / 255.0,
+      SWFDEC_COLOR_B (color) / 255.0, SWFDEC_COLOR_A (color) / 255.0);
 }
 
 unsigned int
@@ -61,10 +61,10 @@ swfdec_color_apply_transform (unsigned i
 {
   int r, g, b, a;
 
-  r = SWF_COLOR_R (in);
-  g = SWF_COLOR_G (in);
-  b = SWF_COLOR_B (in);
-  a = SWF_COLOR_A (in);
+  r = SWFDEC_COLOR_R (in);
+  g = SWFDEC_COLOR_G (in);
+  b = SWFDEC_COLOR_B (in);
+  a = SWFDEC_COLOR_A (in);
 
   SWFDEC_LOG ("in rgba %d,%d,%d,%d", r, g, b, a);
 
@@ -80,7 +80,7 @@ swfdec_color_apply_transform (unsigned i
 
   SWFDEC_LOG ("out rgba %d,%d,%d,%d", r, g, b, a);
 
-  return SWF_COLOR_COMBINE (r, g, b, a);
+  return SWFDEC_COLOR_COMBINE (r, g, b, a);
 }
 
 /**
@@ -116,13 +116,13 @@ void
 swfdec_color_transform_init_color (SwfdecColorTransform *trans, SwfdecColor color)
 {
   trans->ra = 0;
-  trans->rb = SWF_COLOR_R (color);
+  trans->rb = SWFDEC_COLOR_R (color);
   trans->ga = 0;
-  trans->gb = SWF_COLOR_G (color);
+  trans->gb = SWFDEC_COLOR_G (color);
   trans->ba = 0;
-  trans->bb = SWF_COLOR_B (color);
+  trans->bb = SWFDEC_COLOR_B (color);
   trans->aa = 0;
-  trans->ab = SWF_COLOR_A (color);
+  trans->ab = SWFDEC_COLOR_A (color);
 }
 
 /**
diff --git a/libswfdec/swfdec_color.h b/libswfdec/swfdec_color.h
index 39e48fe..07870c3 100644
--- a/libswfdec/swfdec_color.h
+++ b/libswfdec/swfdec_color.h
@@ -46,11 +46,11 @@ struct swfdec_gradient_struct
   SwfdecGradientEntry array[1];
 };
 
-#define SWF_COLOR_COMBINE(r,g,b,a)	(((r)<<24) | ((g)<<16) | ((b)<<8) | (a))
-#define SWF_COLOR_R(x)		(((x)>>24)&0xff)
-#define SWF_COLOR_G(x)		(((x)>>16)&0xff)
-#define SWF_COLOR_B(x)		(((x)>>8)&0xff)
-#define SWF_COLOR_A(x)		((x)&0xff)
+#define SWFDEC_COLOR_COMBINE(r,g,b,a)	(((r)<<24) | ((g)<<16) | ((b)<<8) | (a))
+#define SWFDEC_COLOR_R(x)		(((x)>>24)&0xff)
+#define SWFDEC_COLOR_G(x)		(((x)>>16)&0xff)
+#define SWFDEC_COLOR_B(x)		(((x)>>8)&0xff)
+#define SWFDEC_COLOR_A(x)		((x)&0xff)
 
 SwfdecColor swfdec_color_apply_morph (SwfdecColor start, SwfdecColor end, unsigned int ratio);
 void swfdec_color_set_source (cairo_t *cr, SwfdecColor color);
diff --git a/libswfdec/swfdec_edittext.c b/libswfdec/swfdec_edittext.c
index d38b33a..37727eb 100644
--- a/libswfdec/swfdec_edittext.c
+++ b/libswfdec/swfdec_edittext.c
@@ -148,7 +148,7 @@ tag_func_define_edit_text (SwfdecSwfDeco
     SWFDEC_LOG ("  color = %u", text->color);
   } else {
     SWFDEC_WARNING ("FIXME: figure out default color");
-    text->color = SWF_COLOR_COMBINE (255, 255, 255, 255);
+    text->color = SWFDEC_COLOR_COMBINE (255, 255, 255, 255);
   }
   if (has_max_length) {
     text->max_length = swfdec_bits_get_u16 (b);
diff --git a/libswfdec/swfdec_pattern.c b/libswfdec/swfdec_pattern.c
index f8902ef..2a614b0 100644
--- a/libswfdec/swfdec_pattern.c
+++ b/libswfdec/swfdec_pattern.c
@@ -278,10 +278,10 @@ swfdec_image_pattern_paint (SwfdecPatter
   cairo_pattern_set_filter (pattern, image->filter);
   cairo_set_source (cr, pattern);
   cairo_pattern_destroy (pattern);
-  if (SWF_COLOR_A (color) < 255) {
+  if (SWFDEC_COLOR_A (color) < 255) {
     cairo_save (cr);
     cairo_clip (cr);
-    cairo_paint_with_alpha (cr, SWF_COLOR_A (color) / 255.);
+    cairo_paint_with_alpha (cr, SWFDEC_COLOR_A (color) / 255.);
     cairo_restore (cr);
   } else {
     cairo_fill (cr);
@@ -368,8 +368,8 @@ swfdec_gradient_pattern_paint (SwfdecPat
 	      gradient->gradient->array[i + 1].ratio * ratio;
       offset /= 65535 * 255;
       cairo_pattern_add_color_stop_rgba (pattern, offset,
-	  SWF_COLOR_R(color) / 255.0, SWF_COLOR_G(color) / 255.0,
-	  SWF_COLOR_B(color) / 255.0, SWF_COLOR_A(color) / 255.0);
+	  SWFDEC_COLOR_R(color) / 255.0, SWFDEC_COLOR_G(color) / 255.0,
+	  SWFDEC_COLOR_B(color) / 255.0, SWFDEC_COLOR_A(color) / 255.0);
     }
   } else {
     for (i = 0; i < gradient->gradient->n_gradients; i++){
@@ -377,8 +377,8 @@ swfdec_gradient_pattern_paint (SwfdecPat
 	  trans);
       offset = gradient->gradient->array[i].ratio / 255.0;
       cairo_pattern_add_color_stop_rgba (pattern, offset,
-	  SWF_COLOR_R(color) / 255.0, SWF_COLOR_G(color) / 255.0,
-	  SWF_COLOR_B(color) / 255.0, SWF_COLOR_A(color) / 255.0);
+	  SWFDEC_COLOR_R(color) / 255.0, SWFDEC_COLOR_G(color) / 255.0,
+	  SWFDEC_COLOR_B(color) / 255.0, SWFDEC_COLOR_A(color) / 255.0);
     }
   }
   cairo_set_source (cr, pattern);
@@ -460,7 +460,7 @@ swfdec_pattern_parse (SwfdecSwfDecoder *
     if (paint_id == 65535) {
       /* FIXME: someone explain this magic paint id here */
       pattern = g_object_new (SWFDEC_TYPE_COLOR_PATTERN, NULL);
-      SWFDEC_COLOR_PATTERN (pattern)->start_color = SWF_COLOR_COMBINE (0, 255, 255, 255);
+      SWFDEC_COLOR_PATTERN (pattern)->start_color = SWFDEC_COLOR_COMBINE (0, 255, 255, 255);
       SWFDEC_COLOR_PATTERN (pattern)->end_color = SWFDEC_COLOR_PATTERN (pattern)->start_color;
       swfdec_bits_get_matrix (bits, &pattern->start_transform, NULL);
       pattern->end_transform = pattern->start_transform;
@@ -540,7 +540,7 @@ swfdec_pattern_parse_morph (SwfdecSwfDec
     if (paint_id == 65535) {
       /* FIXME: someone explain this magic paint id here */
       pattern = g_object_new (SWFDEC_TYPE_COLOR_PATTERN, NULL);
-      SWFDEC_COLOR_PATTERN (pattern)->start_color = SWF_COLOR_COMBINE (0, 255, 255, 255);
+      SWFDEC_COLOR_PATTERN (pattern)->start_color = SWFDEC_COLOR_COMBINE (0, 255, 255, 255);
       SWFDEC_COLOR_PATTERN (pattern)->end_color = SWFDEC_COLOR_PATTERN (pattern)->start_color;
       swfdec_bits_get_matrix (bits, &pattern->start_transform, NULL);
       swfdec_bits_get_matrix (bits, &pattern->end_transform, NULL);
diff --git a/libswfdec/swfdec_sprite.c b/libswfdec/swfdec_sprite.c
index 9201218..074bb37 100644
--- a/libswfdec/swfdec_sprite.c
+++ b/libswfdec/swfdec_sprite.c
@@ -503,7 +503,7 @@ swfdec_sprite_set_n_frames (SwfdecSprite
     sprite->frames[i].sound_samples = 44100 * 256 / rate;
   }
   /* default bg is white */
-  sprite->frames[0].bg_color = SWF_COLOR_COMBINE (0xFF, 0xFF, 0xFF, 0xFF);
+  sprite->frames[0].bg_color = SWFDEC_COLOR_COMBINE (0xFF, 0xFF, 0xFF, 0xFF);
 
   SWFDEC_LOG ("n_frames = %d", sprite->n_frames);
 }


More information about the Swfdec mailing list