[Swfdec] libswfdec/swfdec_image.c libswfdec/swfdec_image.h libswfdec/swfdec_pattern.c

Benjamin Otte company at kemper.freedesktop.org
Fri Jan 26 13:54:25 PST 2007


 libswfdec/swfdec_image.c   |   45 ++++++++++++++++++++++++++++++++++++++-------
 libswfdec/swfdec_image.h   |    5 ++++-
 libswfdec/swfdec_pattern.c |    3 ++-
 3 files changed, 44 insertions(+), 9 deletions(-)

New commits:
diff-tree 2cb8680a8577ff5d018b50e7da55c233e8eaa4af (from 7005f0c65edf0177ea22cbb4514c7df1cbb099c1)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Jan 26 22:54:14 2007 +0100

    implement caching in the target's surface type
    
    This is a naive way that only caches in the last used format,
    but it should be good enough for most uses

diff --git a/libswfdec/swfdec_image.c b/libswfdec/swfdec_image.c
index 6c2dcae..0cf6502 100644
--- a/libswfdec/swfdec_image.c
+++ b/libswfdec/swfdec_image.c
@@ -185,15 +185,15 @@ tag_func_define_bits_jpeg (SwfdecSwfDeco
 }
 
 static void
-swfdec_image_create_surface (SwfdecImage *image, guint8 *data)
+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,
-      CAIRO_FORMAT_ARGB32, image->width, image->height,
-      image->rowstride);
+      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);
 }
@@ -220,7 +220,7 @@ swfdec_image_jpeg_load (SwfdecImage *ima
   jpeg_rgb_decoder_get_image (dec, &image_data,
       &image->rowstride, NULL, NULL);
   jpeg_rgb_decoder_free (dec);
-  swfdec_image_create_surface (image, image_data);
+  swfdec_image_create_surface (image, image_data, FALSE);
 
   SWFDEC_LOG ("  width = %d", image->width);
   SWFDEC_LOG ("  height = %d", image->height);
@@ -268,7 +268,7 @@ swfdec_image_jpeg2_load (SwfdecImage *im
   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);
+  swfdec_image_create_surface (image, image_data, FALSE);
 
   SWFDEC_LOG ("  width = %d", image->width);
   SWFDEC_LOG ("  height = %d", image->height);
@@ -339,7 +339,7 @@ swfdec_image_jpeg3_load (SwfdecImage *im
   merge_alpha (image, image_data, alpha_data);
   g_free (alpha_data);
 
-  swfdec_image_create_surface (image, image_data);
+  swfdec_image_create_surface (image, image_data, TRUE);
 
   SWFDEC_LOG ("  width = %d", image->width);
   SWFDEC_LOG ("  height = %d", image->height);
@@ -464,6 +464,7 @@ swfdec_image_lossless_load (SwfdecImage 
 
     if (have_alpha) {
       SWFDEC_INFO("16bit images aren't allowed to have alpha, ignoring");
+      have_alpha = FALSE;
     }
 
     image_data = g_malloc (4 * image->width * image->height);
@@ -513,7 +514,7 @@ swfdec_image_lossless_load (SwfdecImage 
     }
   }
 
-  swfdec_image_create_surface (image, image_data);
+  swfdec_image_create_surface (image, image_data, have_alpha);
 }
 
 int
@@ -626,3 +627,33 @@ swfdec_image_get_surface (SwfdecImage *i
   return image->surface;
 }
 
+cairo_surface_t *
+swfdec_image_get_surface_for_target (SwfdecImage *image, cairo_surface_t *target)
+{
+  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;
+}
diff --git a/libswfdec/swfdec_image.h b/libswfdec/swfdec_image.h
index af230f2..bcd22f0 100644
--- a/libswfdec/swfdec_image.h
+++ b/libswfdec/swfdec_image.h
@@ -65,7 +65,10 @@ struct _SwfdecImageClass {
 
 GType			swfdec_image_get_type		(void);
 
-cairo_surface_t *	swfdec_image_get_surface	(SwfdecImage *	image);
+cairo_surface_t *	swfdec_image_get_surface	(SwfdecImage *		image);
+cairo_surface_t *	swfdec_image_get_surface_for_target 
+							(SwfdecImage *		image,
+							 cairo_surface_t *	target);
 
 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 312118f..f8902ef 100644
--- a/libswfdec/swfdec_pattern.c
+++ b/libswfdec/swfdec_pattern.c
@@ -267,7 +267,8 @@ swfdec_image_pattern_paint (SwfdecPatter
   cairo_matrix_t mat;
   cairo_surface_t *surface;
   
-  surface = swfdec_image_get_surface (image->image);
+  surface = swfdec_image_get_surface_for_target (image->image, 
+      cairo_get_target (cr));
   cairo_append_path (cr, (cairo_path_t *) path);
   color = swfdec_color_apply_transform (0xFFFFFFFF, trans);
   pattern = cairo_pattern_create_for_surface (surface);


More information about the Swfdec mailing list