[Swfdec-commits] 7 commits - swfdec-gtk/swfdec_gtk_widget.c swfdec/jpeg swfdec/swfdec_image.c swfdec/swfdec_image.h swfdec/swfdec_player.c swfdec/swfdec_player_internal.h swfdec/swfdec_renderer.c swfdec/swfdec_renderer_internal.h swfdec/swfdec_sprite_movie.c swfdec/swfdec_tag.c test/image

Benjamin Otte company at kemper.freedesktop.org
Wed Apr 16 03:12:09 PDT 2008


 swfdec-gtk/swfdec_gtk_widget.c               |   24 +++++++---
 swfdec/jpeg/jpeg.c                           |    6 +-
 swfdec/jpeg/jpeg.h                           |    4 -
 swfdec/jpeg/jpeg_rgb_decoder.c               |    2 
 swfdec/jpeg/jpeg_rgb_decoder.h               |    2 
 swfdec/swfdec_image.c                        |   55 +++++++++++++++++++-----
 swfdec/swfdec_image.h                        |    5 +-
 swfdec/swfdec_player.c                       |   61 ++++++++++++++++++++-------
 swfdec/swfdec_player_internal.h              |    4 +
 swfdec/swfdec_renderer.c                     |    8 +++
 swfdec/swfdec_renderer_internal.h            |    2 
 swfdec/swfdec_sprite_movie.c                 |   24 +---------
 swfdec/swfdec_tag.c                          |    2 
 test/image/Makefile.am                       |   27 +++++++++++
 test/image/background-load-5.swf             |binary
 test/image/background-load-5.swf.png         |binary
 test/image/background-load-6.swf             |binary
 test/image/background-load-6.swf.png         |binary
 test/image/background-load-7.swf             |binary
 test/image/background-load-7.swf.png         |binary
 test/image/background-load-8.swf             |binary
 test/image/background-load-8.swf.png         |binary
 test/image/background-load.xml               |   18 +++++++
 test/image/background-set-and-load-5.swf     |binary
 test/image/background-set-and-load-5.swf.png |binary
 test/image/background-set-and-load-6.swf     |binary
 test/image/background-set-and-load-6.swf.png |binary
 test/image/background-set-and-load-7.swf     |binary
 test/image/background-set-and-load-7.swf.png |binary
 test/image/background-set-and-load-8.swf     |binary
 test/image/background-set-and-load-8.swf.png |binary
 test/image/background-set-and-load.xml       |   31 +++++++++++++
 test/image/crash-0.6.4-huge-image-5.swf      |binary
 test/image/crash-0.6.4-huge-image-5.swf.png  |binary
 test/image/crash-0.6.4-huge-image-6.swf      |binary
 test/image/crash-0.6.4-huge-image-6.swf.png  |binary
 test/image/crash-0.6.4-huge-image-7.swf      |binary
 test/image/crash-0.6.4-huge-image-7.swf.png  |binary
 test/image/crash-0.6.4-huge-image-8.swf      |binary
 test/image/crash-0.6.4-huge-image-8.swf.png  |binary
 test/image/crash-0.6.4-huge-image.xml        |   45 +++++++++++++++++++
 41 files changed, 255 insertions(+), 65 deletions(-)

New commits:
commit 5f89bb476a9222e32c94f4cb5173410a11bcb5e9
Merge: d40c079... eae9c99...
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Apr 16 12:11:04 2008 +0200

    Merge branch '0.6'
    
    Conflicts:
    
    	swfdec/swfdec_image.c

commit eae9c9930fac714958c50a858ee3ae6bd25f95b7
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Apr 16 12:02:56 2008 +0200

    add test for latest fix

diff --git a/test/image/Makefile.am b/test/image/Makefile.am
index f33ab90..20d6be5 100644
--- a/test/image/Makefile.am
+++ b/test/image/Makefile.am
@@ -44,6 +44,15 @@ EXTRA_DIST = \
 	color-transform-add80.swf.png \
 	color-transform-add80-alpha.swf \
 	color-transform-add80-alpha.swf.png \
+	crash-0.6.4-huge-image-5.swf \
+	crash-0.6.4-huge-image-5.swf.png \
+	crash-0.6.4-huge-image-6.swf \
+	crash-0.6.4-huge-image-6.swf.png \
+	crash-0.6.4-huge-image-7.swf \
+	crash-0.6.4-huge-image-7.swf.png \
+	crash-0.6.4-huge-image-8.swf \
+	crash-0.6.4-huge-image-8.swf.png \
+	crash-0.6.4-huge-image.xml \
 	default.stas \
 	default.sts \
 	definebits-palette-5.swf \
diff --git a/test/image/crash-0.6.4-huge-image-5.swf b/test/image/crash-0.6.4-huge-image-5.swf
new file mode 100644
index 0000000..5100435
Binary files /dev/null and b/test/image/crash-0.6.4-huge-image-5.swf differ
diff --git a/test/image/crash-0.6.4-huge-image-5.swf.png b/test/image/crash-0.6.4-huge-image-5.swf.png
new file mode 100644
index 0000000..fca17d2
Binary files /dev/null and b/test/image/crash-0.6.4-huge-image-5.swf.png differ
diff --git a/test/image/crash-0.6.4-huge-image-6.swf b/test/image/crash-0.6.4-huge-image-6.swf
new file mode 100644
index 0000000..8d6f1f7
Binary files /dev/null and b/test/image/crash-0.6.4-huge-image-6.swf differ
diff --git a/test/image/crash-0.6.4-huge-image-6.swf.png b/test/image/crash-0.6.4-huge-image-6.swf.png
new file mode 100644
index 0000000..fca17d2
Binary files /dev/null and b/test/image/crash-0.6.4-huge-image-6.swf.png differ
diff --git a/test/image/crash-0.6.4-huge-image-7.swf b/test/image/crash-0.6.4-huge-image-7.swf
new file mode 100644
index 0000000..c2d0056
Binary files /dev/null and b/test/image/crash-0.6.4-huge-image-7.swf differ
diff --git a/test/image/crash-0.6.4-huge-image-7.swf.png b/test/image/crash-0.6.4-huge-image-7.swf.png
new file mode 100644
index 0000000..fca17d2
Binary files /dev/null and b/test/image/crash-0.6.4-huge-image-7.swf.png differ
diff --git a/test/image/crash-0.6.4-huge-image-8.swf b/test/image/crash-0.6.4-huge-image-8.swf
new file mode 100644
index 0000000..b92d00d
Binary files /dev/null and b/test/image/crash-0.6.4-huge-image-8.swf differ
diff --git a/test/image/crash-0.6.4-huge-image-8.swf.png b/test/image/crash-0.6.4-huge-image-8.swf.png
new file mode 100644
index 0000000..fca17d2
Binary files /dev/null and b/test/image/crash-0.6.4-huge-image-8.swf.png differ
diff --git a/test/image/crash-0.6.4-huge-image.xml b/test/image/crash-0.6.4-huge-image.xml
new file mode 100644
index 0000000..7d3300c
--- /dev/null
+++ b/test/image/crash-0.6.4-huge-image.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<swf version="7" compressed="1">
+  <Header framerate="31" frames="27">
+    <size>
+      <Rectangle left="0" right="4000" top="0" bottom="3000"/>
+    </size>
+    <tags>
+
+      <DefineBitsLossless objectID="1" format="5" width="62525" height="17173">
+        <data>
+	  <data>eNpjYGBgAAAABAABAA==</data>
+        </data>
+      </DefineBitsLossless>
+      <DefineShape objectID="2">
+        <bounds>
+          <Rectangle left="0" right="4000" top="0" bottom="3000"/>
+        </bounds>
+        <styles>
+          <StyleList>
+            <fillStyles>
+	      <ClippedBitmap objectID="1" />
+            </fillStyles>
+            <lineStyles/>
+          </StyleList>
+        </styles>
+        <shapes>
+          <Shape>
+            <edges>
+              <ShapeSetup fillStyle1="1"/>
+              <LineTo x="4000" y="0"/>
+              <LineTo x="0" y="3000"/>
+              <LineTo x="-4000" y="0"/>
+              <LineTo x="0" y="-3000"/>
+              <ShapeSetup/>
+            </edges>
+          </Shape>
+        </shapes>
+      </DefineShape>
+      <PlaceObject2 replace="0" depth="1" objectID="2" />
+
+      <ShowFrame/>
+      <End/>
+    </tags>
+  </Header>
+</swf>
commit 8e2db4e7340135fb07f42a6c1409988293d2f843
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Apr 16 12:01:52 2008 +0200

    don't parse oversized images

diff --git a/swfdec/swfdec_image.c b/swfdec/swfdec_image.c
index fc54511..beb132a 100644
--- a/swfdec/swfdec_image.c
+++ b/swfdec/swfdec_image.c
@@ -338,6 +338,9 @@ swfdec_image_lossless_load (SwfdecImage *image)
 
   if (image->width == 0 || image->height == 0)
     return;
+  if (G_MAXUINT / 4 / image->width < (guint) image->height)
+    return;
+
   swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height);
 
   if (format == 3) {
commit d40c079a0ffc55b30f5d19a8a7d8f2c2bffc6572
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Apr 16 11:48:14 2008 +0200

    check image sizes before blindly using them
    
    Fixes various SEGVs due to doing malloc (width * height * 4) without bounds
    checking.
    THe JPEG decoder needs a similar audit for this.

diff --git a/swfdec/jpeg/jpeg.c b/swfdec/jpeg/jpeg.c
index 52143dc..7ff4187 100644
--- a/swfdec/jpeg/jpeg.c
+++ b/swfdec/jpeg/jpeg.c
@@ -995,12 +995,12 @@ jpeg_decoder_addbits (JpegDecoder * dec, unsigned char *data, unsigned int len)
 }
 
 int
-jpeg_decoder_get_image_size (JpegDecoder * dec, int *width, int *height)
+jpeg_decoder_get_image_size (JpegDecoder * dec, unsigned int *width, unsigned int *height)
 {
   if (width)
-    *width = dec->width;
+    *width = (unsigned) dec->width;
   if (height)
-    *height = dec->height;
+    *height = (unsigned) dec->height;
 
   return 0;
 }
diff --git a/swfdec/jpeg/jpeg.h b/swfdec/jpeg/jpeg.h
index 6c0ba41..a52bb9b 100644
--- a/swfdec/jpeg/jpeg.h
+++ b/swfdec/jpeg/jpeg.h
@@ -147,7 +147,7 @@ JpegDecoder *jpeg_decoder_new(void);
 void jpeg_decoder_free(JpegDecoder *dec);
 int jpeg_decoder_addbits(JpegDecoder *dec, unsigned char *data, unsigned int len);
 int jpeg_decoder_decode (JpegDecoder *dec);
-int jpeg_decoder_get_image_size(JpegDecoder *dec, int *width, int *height);
+int jpeg_decoder_get_image_size(JpegDecoder *dec, unsigned int *width, unsigned int *height);
 int jpeg_decoder_get_component_size(JpegDecoder *dec, int id,
 	int *width, int *height);
 int jpeg_decoder_get_component_subsampling(JpegDecoder *dec, int id,
@@ -157,7 +157,7 @@ int jpeg_decoder_get_component_ptr(JpegDecoder *dec, int id,
 
 uint32_t *jpeg_decoder_get_argb_image (JpegDecoder *dec);
 int jpeg_decode_argb (uint8_t *data, int length, uint32_t **image,
-    int *width, int *height);
+    unsigned int *width, unsigned int *height);
 
 void jpeg_decoder_error(JpegDecoder *dec, const char *fmt, ...);
 
diff --git a/swfdec/jpeg/jpeg_rgb_decoder.c b/swfdec/jpeg/jpeg_rgb_decoder.c
index 3c01914..aeae651 100644
--- a/swfdec/jpeg/jpeg_rgb_decoder.c
+++ b/swfdec/jpeg/jpeg_rgb_decoder.c
@@ -47,7 +47,7 @@ static void scanlinescale2_u8 (unsigned char *dest, unsigned char *src,
 
 
 int jpeg_decode_argb (uint8_t *data, int length, uint32_t **image,
-    int *width, int *height)
+    unsigned int *width, unsigned int *height)
 {
   JpegDecoder *dec;
   int ret;
diff --git a/swfdec/jpeg/jpeg_rgb_decoder.h b/swfdec/jpeg/jpeg_rgb_decoder.h
index 08501ff..68823ef 100644
--- a/swfdec/jpeg/jpeg_rgb_decoder.h
+++ b/swfdec/jpeg/jpeg_rgb_decoder.h
@@ -10,7 +10,7 @@ void jpeg_rgb_decoder_free(JpegRGBDecoder *dec);
 int jpeg_rgb_decoder_addbits(JpegRGBDecoder *dec, unsigned char *data, unsigned int len);
 int jpeg_rgb_decoder_parse(JpegRGBDecoder *dec);
 int jpeg_rgb_decoder_get_image(JpegRGBDecoder *dec,
-	unsigned char **image, int *rowstride, int *width, int *height);
+	unsigned char **image, int *rowstride, unsigned int *width, unsigned int *height);
 
 
 
diff --git a/swfdec/swfdec_image.c b/swfdec/swfdec_image.c
index 2885969..3fa65a1 100644
--- a/swfdec/swfdec_image.c
+++ b/swfdec/swfdec_image.c
@@ -29,6 +29,7 @@
 
 #include "jpeg.h"
 #include "swfdec_image.h"
+#include "swfdec_cache.h"
 #include "swfdec_cached_image.h"
 #include "swfdec_debug.h"
 #include "swfdec_renderer_internal.h"
@@ -108,6 +109,29 @@ tag_func_define_bits_jpeg (SwfdecSwfDecoder * s, guint tag)
   return SWFDEC_STATUS_OK;
 }
 
+static gboolean
+swfdec_image_validate_size (SwfdecRenderer *renderer, guint width, guint height)
+{
+  gsize size;
+
+  if (width == 0 || height == 0)
+    return FALSE;
+
+  if (renderer) {
+    size = swfdec_renderer_get_max_cache_size (renderer);
+    size = MIN (size, G_MAXUINT);
+  } else {
+    size = G_MAXUINT;
+  }
+  if (size / 4 / width < height) {
+    SWFDEC_INFO ("%ux%u image doesn't fit into %zu bytes of cache", 
+	width, height, size);
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
 /**
  * swfdec_jpeg_decode_argb:
  *
@@ -117,9 +141,10 @@ tag_func_define_bits_jpeg (SwfdecSwfDecoder * s, guint tag)
  * buffer.  This makes a real JPEG image out of the crap in SWF files.
  */
 static gboolean
-swfdec_jpeg_decode_argb (unsigned char *data1, int length1,
+swfdec_jpeg_decode_argb (SwfdecRenderer *renderer,
+    unsigned char *data1, int length1,
     unsigned char *data2, int length2,
-    void *outdata, int *width, int *height)
+    void *outdata, guint *width, guint *height)
 {
   gboolean ret;
 
@@ -141,6 +166,8 @@ swfdec_jpeg_decode_argb (unsigned char *data1, int length1,
     ret = FALSE;
   }
 
+  if (ret)
+    ret = swfdec_image_validate_size (renderer, *width, *height);
   return ret;
 }
 
@@ -168,12 +195,12 @@ swfdec_image_jpeg_load (SwfdecImage *image, SwfdecRenderer *renderer)
   guint8 *data;
 
   if (image->jpegtables) {
-    ret = swfdec_jpeg_decode_argb (
+    ret = swfdec_jpeg_decode_argb (renderer,
         image->jpegtables->data, image->jpegtables->length,
         image->raw_data->data, image->raw_data->length,
         (void *) &data, &image->width, &image->height);
   } else {
-    ret = swfdec_jpeg_decode_argb (
+    ret = swfdec_jpeg_decode_argb (renderer,
         image->raw_data->data, image->raw_data->length,
         NULL, 0,
         (void *)&data, &image->width, &image->height);
@@ -215,7 +242,7 @@ swfdec_image_jpeg2_load (SwfdecImage *image, SwfdecRenderer *renderer)
   gboolean ret;
   guint8 *data;
 
-  ret = swfdec_jpeg_decode_argb (image->raw_data->data, image->raw_data->length,
+  ret = swfdec_jpeg_decode_argb (renderer, image->raw_data->data, image->raw_data->length,
       NULL, 0,
       (void *)&data, &image->width, &image->height);
   if (!ret)
@@ -252,7 +279,7 @@ static void
 merge_alpha (SwfdecImage * image, unsigned char *image_data,
     unsigned char *alpha)
 {
-  int x, y;
+  unsigned int x, y;
   unsigned char *p;
 
   for (y = 0; y < image->height; y++) {
@@ -281,8 +308,8 @@ swfdec_image_jpeg3_load (SwfdecImage *image, SwfdecRenderer *renderer)
   if (buffer == NULL)
     return NULL;
 
-  ret = swfdec_jpeg_decode_argb (buffer->data, buffer->length,
-      NULL, 0,
+  ret = swfdec_jpeg_decode_argb (renderer,
+      buffer->data, buffer->length, NULL, 0,
       (void *)&data, &image->width, &image->height);
   swfdec_buffer_unref (buffer);
 
@@ -326,7 +353,7 @@ swfdec_image_lossless_load (SwfdecImage *image, SwfdecRenderer *renderer)
   SWFDEC_LOG ("width = %d", image->width);
   SWFDEC_LOG ("height = %d", image->height);
 
-  if (image->width == 0 || image->height == 0)
+  if (!swfdec_image_validate_size (renderer, image->width, image->height))
     return NULL;
 
   if (format == 3) {
@@ -383,7 +410,7 @@ swfdec_image_lossless_load (SwfdecImage *image, SwfdecRenderer *renderer)
 
     swfdec_buffer_unref (buffer);
   } else if (format == 4) {
-    int i, j;
+    guint i, j;
     guint c;
     unsigned char *idata;
     SwfdecBuffer *buffer;
@@ -420,7 +447,7 @@ swfdec_image_lossless_load (SwfdecImage *image, SwfdecRenderer *renderer)
     swfdec_buffer_unref (buffer);
   } else if (format == 5) {
     SwfdecBuffer *buffer;
-    int i, j;
+    guint i, j;
     guint32 *p;
 
     buffer = swfdec_bits_decompress (&bits, -1, 4 * image->width * image->height);
@@ -514,12 +541,18 @@ swfdec_image_png_load (SwfdecImage *image, SwfdecRenderer *renderer)
   surface = cairo_image_surface_create_from_png_stream (
       swfdec_image_png_read, &bits);
   if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) {
+    SWFDEC_ERROR ("could not create PNG image: %s", 
+	cairo_status_to_string (cairo_surface_status (surface)));
     cairo_surface_destroy (surface);
     return NULL;
   }
 
   image->width = cairo_image_surface_get_width (surface);
   image->height = cairo_image_surface_get_height (surface);
+  if (!swfdec_image_validate_size (renderer, image->width, image->height)) {
+    cairo_surface_destroy (surface);
+    return NULL;
+  }
   if (renderer)
     surface = swfdec_renderer_create_similar (renderer, surface);
   return surface;
diff --git a/swfdec/swfdec_image.h b/swfdec/swfdec_image.h
index b127e5d..dfe44b4 100644
--- a/swfdec/swfdec_image.h
+++ b/swfdec/swfdec_image.h
@@ -51,8 +51,9 @@ typedef enum {
 struct _SwfdecImage {
   SwfdecCharacter	character;
 
-  int			width;		/* width of image or 0 if not known yet */
-  int			height;		/* height of image or 0 if not known yet */
+  /* width * height * 4 must fit into a guint */
+  guint			width;		/* width of image or 0 if not known yet */
+  guint			height;		/* height of image or 0 if not known yet */
 
   SwfdecImageType	type;
   SwfdecBuffer *	jpegtables;
diff --git a/swfdec/swfdec_renderer.c b/swfdec/swfdec_renderer.c
index 2bc7d23..532511b 100644
--- a/swfdec/swfdec_renderer.c
+++ b/swfdec/swfdec_renderer.c
@@ -267,6 +267,14 @@ swfdec_renderer_get_cache (SwfdecRenderer *renderer, gpointer key,
   return result;
 }
 
+gsize
+swfdec_renderer_get_max_cache_size (SwfdecRenderer *renderer)
+{
+  g_return_val_if_fail (SWFDEC_IS_RENDERER (renderer), 0);
+
+  return swfdec_cache_get_max_cache_size (renderer->priv->cache);
+}
+
 SwfdecRenderer *
 swfdec_renderer_new_default (SwfdecPlayer *player)
 {
diff --git a/swfdec/swfdec_renderer_internal.h b/swfdec/swfdec_renderer_internal.h
index f757ccd..7186ab0 100644
--- a/swfdec/swfdec_renderer_internal.h
+++ b/swfdec/swfdec_renderer_internal.h
@@ -41,6 +41,8 @@ SwfdecCached *		swfdec_renderer_get_cache	(SwfdecRenderer *	renderer,
 							 gpointer		key,
 							 SwfdecRendererSearchFunc func,
 							 gpointer		data);
+gsize			swfdec_renderer_get_max_cache_size
+							(SwfdecRenderer *	renderer);
 
 cairo_surface_t *	swfdec_renderer_create_similar	(SwfdecRenderer *	renderer,
 							 cairo_surface_t *	surface);
commit f43a9d347f324c126acec908fb5421f94d6e9f7a
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Apr 16 10:22:38 2008 +0200

    rewrite background handling once again
    
    This time to make it actually work (I hope).

diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index 5de9ec0..7d7a748 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -2276,24 +2276,31 @@ swfdec_player_stop_sounds (SwfdecPlayer *player, SwfdecAudioRemoveFunc func, gpo
 void
 swfdec_player_invalidate (SwfdecPlayer *player, const SwfdecRect *rect)
 {
-  SwfdecPlayerPrivate *priv = player->priv;
+  SwfdecPlayerPrivate *priv;
   SwfdecRectangle r;
   SwfdecRect tmp;
   guint i;
 
-  if (swfdec_rect_is_empty (rect))
-    return;
+  g_return_if_fail (SWFDEC_IS_PLAYER (player));
 
-  tmp = *rect;
-  swfdec_player_global_to_stage (player, &tmp.x0, &tmp.y0);
-  swfdec_player_global_to_stage (player, &tmp.x1, &tmp.y1);
-  swfdec_rectangle_init_rect (&r, &tmp);
-  /* FIXME: currently we clamp the rectangle to the visible area, it might
-   * be useful to allow out-of-bounds drawing. In that case this needs to be
-   * changed */
-  swfdec_rectangle_intersect (&r, &r, &priv->stage);
-  if (swfdec_rectangle_is_empty (&r))
-    return;
+  priv = player->priv;
+  if (rect == NULL) {
+    r = priv->stage;
+  } else {
+    if (swfdec_rect_is_empty (rect))
+      return;
+
+    tmp = *rect;
+    swfdec_player_global_to_stage (player, &tmp.x0, &tmp.y0);
+    swfdec_player_global_to_stage (player, &tmp.x1, &tmp.y1);
+    swfdec_rectangle_init_rect (&r, &tmp);
+    /* FIXME: currently we clamp the rectangle to the visible area, it might
+     * be useful to allow out-of-bounds drawing. In that case this needs to be
+     * changed */
+    swfdec_rectangle_intersect (&r, &r, &priv->stage);
+    if (swfdec_rectangle_is_empty (&r))
+      return;
+  }
 
   SWFDEC_LOG ("  invalidating %d %d  %d %d", r.x, r.y, r.width, r.height);
   /* FIXME: get region code into swfdec? */
@@ -2304,20 +2311,39 @@ swfdec_player_invalidate (SwfdecPlayer *player, const SwfdecRect *rect)
     if (swfdec_rectangle_contains (&r, cur)) {
       *cur = r;
       swfdec_rectangle_union (&priv->invalid_extents, &priv->invalid_extents, &r);
+      break;
     }
   }
   if (i == priv->invalidations->len) {
     g_array_append_val (priv->invalidations, r);
     swfdec_rectangle_union (&priv->invalid_extents, &priv->invalid_extents, &r);
   }
-  SWFDEC_DEBUG ("toplevel invalidation of %g %g  %g %g - invalid region now %d %d  %d %d (%u subregions)",
-      rect->x0, rect->y0, rect->x1, rect->y1,
+  SWFDEC_DEBUG ("toplevel invalidation of %d %d  %d %d - invalid region now %d %d  %d %d (%u subregions)",
+      r.x, r.y, r.width, r.height,
       priv->invalid_extents.x, priv->invalid_extents.y, 
       priv->invalid_extents.x + priv->invalid_extents.width,
       priv->invalid_extents.y + priv->invalid_extents.height,
       priv->invalidations->len);
 }
 
+void
+swfdec_player_set_background_color (SwfdecPlayer *player, SwfdecColor bgcolor)
+{
+  SwfdecPlayerPrivate *priv;
+
+  g_return_if_fail (SWFDEC_IS_PLAYER (player));
+
+  priv = player->priv;
+  if (priv->bgcolor) {
+    SWFDEC_DEBUG ("not setting background color twice");
+    return;
+  }
+
+  SWFDEC_INFO ("setting bgcolor to %08X", bgcolor);
+  priv->bgcolor = bgcolor;
+  swfdec_player_invalidate (player, NULL);
+}
+
 /**
  * swfdec_player_get_level:
  * @player: a #SwfdecPlayer
@@ -2963,6 +2989,11 @@ swfdec_player_render_with_renderer (SwfdecPlayer *player, cairo_t *cr,
   cairo_save (cr);
   cairo_rectangle (cr, x, y, width, height);
   cairo_clip (cr);
+  /* paint the background */
+  if (priv->bgcolor) {
+    swfdec_color_set_source (cr, priv->bgcolor);
+    cairo_paint (cr);
+  }
   /* compute the rectangle */
   x -= priv->offset_x;
   y -= priv->offset_y;
diff --git a/swfdec/swfdec_player_internal.h b/swfdec/swfdec_player_internal.h
index bafcaf7..c2f97e7 100644
--- a/swfdec/swfdec_player_internal.h
+++ b/swfdec/swfdec_player_internal.h
@@ -95,6 +95,7 @@ struct _SwfdecPlayerPrivate
   double		scale_y;		/* cached y scale value */
   int			offset_x;		/* x offset from top left edge after scaling */
   int			offset_y;		/* y offset from top left edge after scaling */
+  SwfdecColor		bgcolor;		/* background color or 0 if unset */
 
   SwfdecFunctionList	resource_requests;	/* all external requested URIs - see swfdec_resource_request.[ch] */
   guint			unnamed_count;		/* variable used for naming unnamed movies */
@@ -223,6 +224,9 @@ void		swfdec_player_add_action_script	(SwfdecPlayer *		player,
 void		swfdec_player_remove_all_actions (SwfdecPlayer *      	player,
 						 SwfdecActor *		actor);
 
+void		swfdec_player_set_background_color
+						(SwfdecPlayer *		player,
+						 SwfdecColor		bgcolor);
 void		swfdec_player_set_fullscreen	(SwfdecPlayer *		player,
 						 gboolean		fullscreen);
 void		swfdec_player_set_drag_movie	(SwfdecPlayer *		player,
diff --git a/swfdec/swfdec_sprite_movie.c b/swfdec/swfdec_sprite_movie.c
index 4a50db2..7735dd6 100644
--- a/swfdec/swfdec_sprite_movie.c
+++ b/swfdec/swfdec_sprite_movie.c
@@ -375,6 +375,9 @@ swfdec_sprite_movie_perform_one_action (SwfdecSpriteMovie *movie, guint tag, Swf
   SWFDEC_LOG ("%p: executing %uth tag %s in frame %u", movie, movie->next_action - 1, 
       swfdec_swf_decoder_get_tag_name (tag), movie->frame);
   switch (tag) {
+    case SWFDEC_TAG_SETBACKGROUNDCOLOR:
+      swfdec_player_set_background_color (player, swfdec_bits_get_color (&bits));
+      return TRUE;
     case SWFDEC_TAG_DOACTION:
       SWFDEC_LOG ("SCRIPT action");
       if (!skip_scripts) {
@@ -760,26 +763,6 @@ swfdec_sprite_movie_finish_movie (SwfdecMovie *mov)
 }
 
 static void
-swfdec_sprite_movie_render (SwfdecMovie *mov, cairo_t *cr,
-    const SwfdecColorTransform *trans, const SwfdecRect *inval)
-{
-  SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (mov);
-  SwfdecResource *resource;
-
-  resource = swfdec_movie_get_own_resource (mov);
-  if (resource && movie->sprite && movie->sprite->bgcolor) {
-    cairo_rectangle (cr, 0, 0, 
-	resource->decoder->width * SWFDEC_TWIPS_SCALE_FACTOR,
-	resource->decoder->height * SWFDEC_TWIPS_SCALE_FACTOR);
-    swfdec_color_set_source (cr, movie->sprite->bgcolor);
-    cairo_fill (cr);
-  }
-
-  SWFDEC_MOVIE_CLASS (swfdec_sprite_movie_parent_class)->render (mov,
-      cr, trans, inval);
-}
-
-static void
 swfdec_sprite_movie_mark (SwfdecAsObject *object)
 {
   GList *walk;
@@ -808,7 +791,6 @@ swfdec_sprite_movie_class_init (SwfdecSpriteMovieClass * g_class)
 
   movie_class->init_movie = swfdec_sprite_movie_init_movie;
   movie_class->finish_movie = swfdec_sprite_movie_finish_movie;
-  movie_class->render = swfdec_sprite_movie_render;
   
   actor_class->iterate_start = swfdec_sprite_movie_iterate;
   actor_class->iterate_end = swfdec_sprite_movie_iterate_end;
diff --git a/swfdec/swfdec_tag.c b/swfdec/swfdec_tag.c
index 1d83bd0..65fa514 100644
--- a/swfdec/swfdec_tag.c
+++ b/swfdec/swfdec_tag.c
@@ -367,7 +367,7 @@ static struct tag_func_struct tag_funcs[] = {
   [SWFDEC_TAG_DEFINEBUTTON] = {"DefineButton", tag_func_define_button, 0},
   [SWFDEC_TAG_JPEGTABLES] = {"JPEGTables", swfdec_image_jpegtables, 0},
   [SWFDEC_TAG_SETBACKGROUNDCOLOR] =
-      {"SetBackgroundColor", tag_func_set_background_color, SWFDEC_TAG_DEFINE_SPRITE },
+      {"SetBackgroundColor", tag_func_enqueue, SWFDEC_TAG_DEFINE_SPRITE },
   [SWFDEC_TAG_DEFINEFONT] = {"DefineFont", tag_func_define_font, 0},
   [SWFDEC_TAG_DEFINETEXT] = {"DefineText", tag_func_define_text, 0},
   [SWFDEC_TAG_DOACTION] = {"DoAction", tag_func_do_action, SWFDEC_TAG_DEFINE_SPRITE },
commit 35e7d92b0aaebacf4631572c53d402ab8c651c06
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Apr 16 10:22:22 2008 +0200

    add more tests for background handling

diff --git a/test/image/Makefile.am b/test/image/Makefile.am
index 1ea37e9..5ae774c 100644
--- a/test/image/Makefile.am
+++ b/test/image/Makefile.am
@@ -12,6 +12,24 @@ EXTRA_DIST = \
 	background-8.swf \
 	background-8.swf.png \
 	background.xml \
+	background-load-5.swf \
+	background-load-5.swf.png \
+	background-load-6.swf \
+	background-load-6.swf.png \
+	background-load-7.swf \
+	background-load-7.swf.png \
+	background-load-8.swf \
+	background-load-8.swf.png \
+	background-load.xml \
+	background-set-and-load-5.swf \
+	background-set-and-load-5.swf.png \
+	background-set-and-load-6.swf \
+	background-set-and-load-6.swf.png \
+	background-set-and-load-7.swf \
+	background-set-and-load-7.swf.png \
+	background-set-and-load-8.swf \
+	background-set-and-load-8.swf.png \
+	background-set-and-load.xml \
 	bw.jpg \
 	clip-change.c \
 	clip-change-backward-5.swf \
diff --git a/test/image/background-load-5.swf b/test/image/background-load-5.swf
new file mode 100644
index 0000000..f9fc508
Binary files /dev/null and b/test/image/background-load-5.swf differ
diff --git a/test/image/background-load-5.swf.png b/test/image/background-load-5.swf.png
new file mode 100644
index 0000000..48437a2
Binary files /dev/null and b/test/image/background-load-5.swf.png differ
diff --git a/test/image/background-load-6.swf b/test/image/background-load-6.swf
new file mode 100644
index 0000000..c7123db
Binary files /dev/null and b/test/image/background-load-6.swf differ
diff --git a/test/image/background-load-6.swf.png b/test/image/background-load-6.swf.png
new file mode 100644
index 0000000..5b95250
Binary files /dev/null and b/test/image/background-load-6.swf.png differ
diff --git a/test/image/background-load-7.swf b/test/image/background-load-7.swf
new file mode 100644
index 0000000..114056f
Binary files /dev/null and b/test/image/background-load-7.swf differ
diff --git a/test/image/background-load-7.swf.png b/test/image/background-load-7.swf.png
new file mode 100644
index 0000000..b653f96
Binary files /dev/null and b/test/image/background-load-7.swf.png differ
diff --git a/test/image/background-load-8.swf b/test/image/background-load-8.swf
new file mode 100644
index 0000000..95a9f40
Binary files /dev/null and b/test/image/background-load-8.swf differ
diff --git a/test/image/background-load-8.swf.png b/test/image/background-load-8.swf.png
new file mode 100644
index 0000000..746935f
Binary files /dev/null and b/test/image/background-load-8.swf.png differ
diff --git a/test/image/background-load.xml b/test/image/background-load.xml
new file mode 100644
index 0000000..bdd9b9f
--- /dev/null
+++ b/test/image/background-load.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<swf version="8" compressed="1">
+  <Header framerate="30" frames="1">
+    <size>
+      <Rectangle left="0" right="4000" top="0" bottom="3000"/>
+    </size>
+    <tags>
+      <FileAttributes hasMetaData="0" useNetwork="0"/>
+      <DoAction>
+	<actions>
+	  <GetURL url="background-7.swf" target="_level1"/>
+	</actions>
+      </DoAction>
+      <ShowFrame/>
+      <End/>
+    </tags>
+  </Header>
+</swf>
diff --git a/test/image/background-set-and-load-5.swf b/test/image/background-set-and-load-5.swf
new file mode 100644
index 0000000..3e047db
Binary files /dev/null and b/test/image/background-set-and-load-5.swf differ
diff --git a/test/image/background-set-and-load-5.swf.png b/test/image/background-set-and-load-5.swf.png
new file mode 100644
index 0000000..e3059e2
Binary files /dev/null and b/test/image/background-set-and-load-5.swf.png differ
diff --git a/test/image/background-set-and-load-6.swf b/test/image/background-set-and-load-6.swf
new file mode 100644
index 0000000..0dc5a61
Binary files /dev/null and b/test/image/background-set-and-load-6.swf differ
diff --git a/test/image/background-set-and-load-6.swf.png b/test/image/background-set-and-load-6.swf.png
new file mode 100644
index 0000000..8b6f171
Binary files /dev/null and b/test/image/background-set-and-load-6.swf.png differ
diff --git a/test/image/background-set-and-load-7.swf b/test/image/background-set-and-load-7.swf
new file mode 100644
index 0000000..1a78906
Binary files /dev/null and b/test/image/background-set-and-load-7.swf differ
diff --git a/test/image/background-set-and-load-7.swf.png b/test/image/background-set-and-load-7.swf.png
new file mode 100644
index 0000000..4d7213e
Binary files /dev/null and b/test/image/background-set-and-load-7.swf.png differ
diff --git a/test/image/background-set-and-load-8.swf b/test/image/background-set-and-load-8.swf
new file mode 100644
index 0000000..9961bab
Binary files /dev/null and b/test/image/background-set-and-load-8.swf differ
diff --git a/test/image/background-set-and-load-8.swf.png b/test/image/background-set-and-load-8.swf.png
new file mode 100644
index 0000000..a3f73ac
Binary files /dev/null and b/test/image/background-set-and-load-8.swf.png differ
diff --git a/test/image/background-set-and-load.xml b/test/image/background-set-and-load.xml
new file mode 100644
index 0000000..e4218d4
--- /dev/null
+++ b/test/image/background-set-and-load.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<swf version="8" compressed="1">
+  <Header framerate="30" frames="3">
+    <size>
+      <Rectangle left="0" right="4000" top="0" bottom="3000"/>
+    </size>
+    <tags>
+      <FileAttributes hasMetaData="0" useNetwork="0"/>
+      <SetBackgroundColor>
+        <color>
+          <Color red="255" green="0" blue="0"/>
+        </color>
+      </SetBackgroundColor>
+      <ShowFrame/>
+      <SetBackgroundColor>
+        <color>
+          <Color red="0" green="255" blue="0"/>
+        </color>
+      </SetBackgroundColor>
+      <ShowFrame/>
+      <DoAction>
+	<actions>
+	  <GetURL url="background-7.swf" target="_level1"/>
+	  <Stop />
+	</actions>
+      </DoAction>
+      <ShowFrame/>
+      <End/>
+    </tags>
+  </Header>
+</swf>
commit fd27904f5585a2eab659068735a1a627a50e8ea4
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Apr 16 09:32:51 2008 +0200

    don't set a new renderer in fullscreen mode
    
    We assume the app fullscreening us already set a proper one.

diff --git a/swfdec-gtk/swfdec_gtk_widget.c b/swfdec-gtk/swfdec_gtk_widget.c
index 1ac6196..eae87c8 100644
--- a/swfdec-gtk/swfdec_gtk_widget.c
+++ b/swfdec-gtk/swfdec_gtk_widget.c
@@ -478,14 +478,22 @@ swfdec_gtk_widget_update_renderer (SwfdecGtkWidget *widget)
     priv->renderer = NULL;
   }
   if (needs_renderer) {
-    cairo_t *cr = gdk_cairo_create (GTK_WIDGET (widget)->window);
-
-    if (priv->renderer_set)
-      g_printerr ("FIXME: create the right renderer\n");
-    priv->renderer = swfdec_renderer_new_for_player (
-	cairo_get_target (cr), priv->player);
-    swfdec_player_set_renderer (priv->player, priv->renderer);
-    cairo_destroy (cr);
+    if (priv->fullscreen_mode) {
+      /* FIXME: We should really use the renderer of the app that 
+       * fullscreened us, but for now, we'll assume that app uses a
+       * similar renderer */
+      priv->renderer = swfdec_player_get_renderer (priv->player);
+      g_object_ref (priv->renderer);
+    } else {
+      cairo_t *cr = gdk_cairo_create (GTK_WIDGET (widget)->window);
+
+      if (priv->renderer_set)
+	g_printerr ("FIXME: create the right renderer\n");
+      priv->renderer = swfdec_renderer_new_for_player (
+	  cairo_get_target (cr), priv->player);
+      swfdec_player_set_renderer (priv->player, priv->renderer);
+      cairo_destroy (cr);
+    }
   }
 }
 


More information about the Swfdec-commits mailing list