[Swfdec] 13 commits - libswfdec/Makefile.am libswfdec/swfdec_decoder.c libswfdec/swfdec_decoder.h libswfdec/swfdec_flv_decoder.c libswfdec/swfdec_flv_decoder.h libswfdec/swfdec_image.c libswfdec/swfdec_image_decoder.c libswfdec/swfdec_image_decoder.h libswfdec/swfdec_image.h libswfdec/swfdec_loader.c libswfdec/swfdec_loader.h libswfdec/swfdec_movie.c libswfdec/swfdec_movie.h libswfdec/swfdec_net_stream.c libswfdec/swfdec_player.c libswfdec/swfdec_resource.c libswfdec/swfdec_swf_decoder.c test/dump.c
Benjamin Otte
company at kemper.freedesktop.org
Mon Nov 12 09:24:07 PST 2007
libswfdec/Makefile.am | 2
libswfdec/swfdec_decoder.c | 16 ++++-
libswfdec/swfdec_decoder.h | 3
libswfdec/swfdec_flv_decoder.c | 19 +++---
libswfdec/swfdec_flv_decoder.h | 1
libswfdec/swfdec_image.c | 29 ++++++---
libswfdec/swfdec_image.h | 1
libswfdec/swfdec_image_decoder.c | 123 +++++++++++++++++++++++++++++++++++++++
libswfdec/swfdec_image_decoder.h | 59 ++++++++++++++++++
libswfdec/swfdec_loader.c | 6 +
libswfdec/swfdec_loader.h | 4 -
libswfdec/swfdec_movie.c | 25 +++++++
libswfdec/swfdec_movie.h | 1
libswfdec/swfdec_net_stream.c | 7 --
libswfdec/swfdec_player.c | 2
libswfdec/swfdec_resource.c | 51 ++++++++++------
libswfdec/swfdec_swf_decoder.c | 13 ++++
test/dump.c | 2
18 files changed, 322 insertions(+), 42 deletions(-)
New commits:
commit c88c1cbe0b7d222e5915e92fa8f94f125434f48c
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Nov 12 18:00:11 2007 +0100
always schedule onLoadInit execution, as it's where we set the image
diff --git a/libswfdec/swfdec_resource.c b/libswfdec/swfdec_resource.c
index 64bb1cd..d5be854 100644
--- a/libswfdec/swfdec_resource.c
+++ b/libswfdec/swfdec_resource.c
@@ -105,7 +105,7 @@ swfdec_resource_loader_target_image (SwfdecResource *instance)
}
/* NB: name must be GC'ed */
-static SwfdecSpriteMovie *
+static void
swfdec_resource_emit_signal (SwfdecResource *resource, const char *name, gboolean progress,
SwfdecAsValue *args, guint n_args)
{
@@ -115,14 +115,19 @@ swfdec_resource_emit_signal (SwfdecResource *resource, const char *name, gboolea
SwfdecAsValue vals[n_args + skip];
if (resource->clip_loader == NULL)
- return NULL;
+ return;
cx = SWFDEC_AS_OBJECT (resource->clip_loader)->context;
g_assert (resource->target);
movie = swfdec_action_lookup_object (cx, SWFDEC_PLAYER (cx)->roots->data,
resource->target, resource->target + strlen (resource->target));
if (!SWFDEC_IS_SPRITE_MOVIE (movie)) {
SWFDEC_DEBUG ("no movie, not emitting signal");
- return NULL;
+ return;
+ }
+ if (name == SWFDEC_AS_STR_onLoadInit &&
+ movie != SWFDEC_AS_OBJECT (resource->movie)) {
+ SWFDEC_INFO ("not emitting onLoadInit - the movie is different");
+ return;
}
SWFDEC_AS_VALUE_SET_STRING (&vals[0], name);
@@ -147,7 +152,6 @@ swfdec_resource_emit_signal (SwfdecResource *resource, const char *name, gboolea
memcpy (&vals[skip], args, sizeof (SwfdecAsValue) * n_args);
swfdec_as_object_call (SWFDEC_AS_OBJECT (resource->clip_loader), SWFDEC_AS_STR_broadcastMessage,
n_args + skip, vals, NULL);
- return SWFDEC_SPRITE_MOVIE (movie);
}
static void
@@ -311,7 +315,6 @@ swfdec_resource_loader_target_eof (SwfdecLoaderTarget *target, SwfdecLoader *loa
{
SwfdecResource *resource = SWFDEC_RESOURCE (target);
SwfdecAsValue val;
- SwfdecSpriteMovie *movie;
swfdec_resource_emit_signal (resource, SWFDEC_AS_STR_onLoadProgress, TRUE, NULL, 0);
if (resource->decoder) {
@@ -321,14 +324,8 @@ swfdec_resource_loader_target_eof (SwfdecLoaderTarget *target, SwfdecLoader *loa
swfdec_loader_set_data_type (loader, dec->data_type);
}
SWFDEC_AS_VALUE_SET_INT (&val, 0); /* FIXME */
- movie = swfdec_resource_emit_signal (resource, SWFDEC_AS_STR_onLoadComplete, FALSE, &val, 1);
- /* FIXME: I bet this is wrong for figuring out if movies should emit onLoadInit */
- if (resource->clip_loader == NULL ||
- movie != resource->movie) {
- resource->state = SWFDEC_RESOURCE_DONE;
- } else {
- resource->state = SWFDEC_RESOURCE_COMPLETE;
- }
+ swfdec_resource_emit_signal (resource, SWFDEC_AS_STR_onLoadComplete, FALSE, &val, 1);
+ resource->state = SWFDEC_RESOURCE_COMPLETE;
}
static void
@@ -551,20 +548,18 @@ swfdec_resource_load (SwfdecPlayer *player, const char *target, const char *url,
gboolean
swfdec_resource_emit_on_load_init (SwfdecResource *resource)
{
- SwfdecMovie *movie;
-
g_return_val_if_fail (SWFDEC_IS_RESOURCE (resource), FALSE);
if (resource->state != SWFDEC_RESOURCE_COMPLETE)
return FALSE;
- movie = SWFDEC_MOVIE (swfdec_resource_emit_signal (resource, SWFDEC_AS_STR_onLoadInit, FALSE, NULL, 0));
+ swfdec_resource_emit_signal (resource, SWFDEC_AS_STR_onLoadInit, FALSE, NULL, 0);
resource->state = SWFDEC_RESOURCE_DONE;
- if (movie && SWFDEC_IS_IMAGE_DECODER (resource->decoder)) {
+ if (resource->movie && SWFDEC_IS_IMAGE_DECODER (resource->decoder)) {
SwfdecImage *image = SWFDEC_IMAGE_DECODER (resource->decoder)->image;
if (image) {
- movie->image = g_object_ref (image);
- swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_CONTENTS);
+ SWFDEC_MOVIE (resource->movie)->image = g_object_ref (image);
+ swfdec_movie_queue_update (SWFDEC_MOVIE (resource->movie), SWFDEC_MOVIE_INVALID_CONTENTS);
}
}
/* free now unneeded resources */
commit 617e03ee5b7af3d2ff46a5d03ec80b7ca6203b29
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Nov 12 17:59:40 2007 +0100
only pop as many actions as exist
off-by-one error here
diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index 7d68208..ea6cb4b 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -344,7 +344,7 @@ swfdec_player_compress_actions (SwfdecRingBuffer *buffer)
SwfdecPlayerAction *action, tmp;
guint i = 0;
- for (i = swfdec_ring_buffer_get_n_elements (buffer) + 1; i > 0; i--) {
+ for (i = swfdec_ring_buffer_get_n_elements (buffer); i > 0; i--) {
action = swfdec_ring_buffer_pop (buffer);
g_assert (action);
if (action->movie == NULL)
commit 60b6471a70c2e0cf9bf9c872022b85544ffe9ed5
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Nov 12 17:24:17 2007 +0100
also copy matrix state when replacing movies
diff --git a/libswfdec/swfdec_resource.c b/libswfdec/swfdec_resource.c
index 51ebff0..64bb1cd 100644
--- a/libswfdec/swfdec_resource.c
+++ b/libswfdec/swfdec_resource.c
@@ -173,11 +173,16 @@ swfdec_resource_replace_movie (SwfdecSpriteMovie *movie, SwfdecResource *resourc
if (copy == NULL)
return FALSE;
copy->original_name = mov->original_name;
+ copy->modified = mov->modified;
+ copy->xscale = mov->xscale;
+ copy->yscale = mov->yscale;
+ copy->rotation = mov->rotation;
/* FIXME: are events copied? If so, wouldn't that be a security issue? */
swfdec_movie_set_static_properties (copy, &mov->original_transform,
&mov->original_ctrans, mov->original_ratio, mov->clip_depth,
mov->blend_mode, NULL);
swfdec_movie_remove (mov);
+ swfdec_movie_queue_update (copy, SWFDEC_MOVIE_INVALID_MATRIX);
return SWFDEC_SPRITE_MOVIE (copy);
}
commit 74c1e34359f4ecfbe78896a42ff6bf3f79b27d14
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Nov 12 17:23:56 2007 +0100
set loader size on decoder
This is needed to report the correct size when loading images
diff --git a/libswfdec/swfdec_resource.c b/libswfdec/swfdec_resource.c
index e6ed60d..51ebff0 100644
--- a/libswfdec/swfdec_resource.c
+++ b/libswfdec/swfdec_resource.c
@@ -252,7 +252,11 @@ swfdec_resource_loader_target_parse (SwfdecLoaderTarget *target, SwfdecLoader *l
if (dec == NULL) {
SWFDEC_ERROR ("no decoder found for format");
} else {
+ glong total;
resource->decoder = dec;
+ total = swfdec_loader_get_size (loader);
+ if (total >= 0)
+ dec->bytes_total = total;
}
}
while (swfdec_buffer_queue_get_depth (loader->queue)) {
commit d53a117dd399129bc205b3c1d60f2519433eba96
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Nov 12 14:16:41 2007 +0100
make the movie display the loaded image
diff --git a/libswfdec/swfdec_resource.c b/libswfdec/swfdec_resource.c
index e24c512..e6ed60d 100644
--- a/libswfdec/swfdec_resource.c
+++ b/libswfdec/swfdec_resource.c
@@ -33,6 +33,7 @@
#include "swfdec_debug.h"
#include "swfdec_decoder.h"
#include "swfdec_flash_security.h"
+#include "swfdec_image_decoder.h"
#include "swfdec_loader_internal.h"
#include "swfdec_loadertarget.h"
#include "swfdec_movie_clip_loader.h"
@@ -541,13 +542,22 @@ swfdec_resource_load (SwfdecPlayer *player, const char *target, const char *url,
gboolean
swfdec_resource_emit_on_load_init (SwfdecResource *resource)
{
+ SwfdecMovie *movie;
+
g_return_val_if_fail (SWFDEC_IS_RESOURCE (resource), FALSE);
if (resource->state != SWFDEC_RESOURCE_COMPLETE)
return FALSE;
- swfdec_resource_emit_signal (resource, SWFDEC_AS_STR_onLoadInit, FALSE, NULL, 0);
+ movie = SWFDEC_MOVIE (swfdec_resource_emit_signal (resource, SWFDEC_AS_STR_onLoadInit, FALSE, NULL, 0));
resource->state = SWFDEC_RESOURCE_DONE;
+ if (movie && SWFDEC_IS_IMAGE_DECODER (resource->decoder)) {
+ SwfdecImage *image = SWFDEC_IMAGE_DECODER (resource->decoder)->image;
+ if (image) {
+ movie->image = g_object_ref (image);
+ swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_CONTENTS);
+ }
+ }
/* free now unneeded resources */
if (resource->clip_loader) {
g_object_unref (resource->clip_loader);
commit 63bd88b77ee4201fc3cc4a32bba7f0a9b6a6a399
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Nov 12 14:09:03 2007 +0100
render an image, if one is set
diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c
index 2f79b06..1aeb0bf 100644
--- a/libswfdec/swfdec_movie.c
+++ b/libswfdec/swfdec_movie.c
@@ -35,6 +35,7 @@
#include "swfdec_draw.h"
#include "swfdec_event.h"
#include "swfdec_graphic.h"
+#include "swfdec_image.h"
#include "swfdec_loader_internal.h"
#include "swfdec_player_internal.h"
#include "swfdec_sprite.h"
@@ -128,6 +129,12 @@ swfdec_movie_update_extents (SwfdecMovie *movie)
SwfdecRect *extents = &movie->extents;
*rect = movie->draw_extents;
+ if (movie->image) {
+ SwfdecRect image_extents = { 0, 0,
+ movie->image->width * SWFDEC_TWIPS_SCALE_FACTOR,
+ movie->image->height * SWFDEC_TWIPS_SCALE_FACTOR };
+ swfdec_rect_union (rect, rect, &image_extents);
+ }
for (walk = movie->list; walk; walk = walk->next) {
swfdec_rect_union (rect, rect, &SWFDEC_MOVIE (walk->data)->extents);
}
@@ -880,6 +887,20 @@ swfdec_movie_render (SwfdecMovie *movie, cairo_t *cr,
swfdec_draw_paint (draw, cr, &trans);
}
+ /* if the movie loaded an image, draw it here now */
+ if (movie->image) {
+ cairo_surface_t *surface = swfdec_image_create_surface_transformed (movie->image,
+ &trans);
+ if (surface) {
+ static const cairo_matrix_t matrix = { 1.0 / SWFDEC_TWIPS_SCALE_FACTOR, 0, 0, 1.0 / SWFDEC_TWIPS_SCALE_FACTOR, 0, 0 };
+ cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface);
+ SWFDEC_LOG ("rendering loaded image");
+ cairo_pattern_set_matrix (pattern, &matrix);
+ cairo_set_source (cr, pattern);
+ cairo_paint (cr);
+ }
+ }
+
/* draw the children movies */
for (g = movie->list; g; g = g_list_next (g)) {
SwfdecMovie *child = g->data;
@@ -1004,6 +1025,10 @@ swfdec_movie_dispose (GObject *object)
g_slist_free (movie->variable_listeners);
movie->variable_listeners = NULL;
+ if (movie->image) {
+ g_object_unref (movie->image);
+ movie->image = NULL;
+ }
g_slist_foreach (movie->draws, (GFunc) g_object_unref, NULL);
g_slist_free (movie->draws);
movie->draws = NULL;
diff --git a/libswfdec/swfdec_movie.h b/libswfdec/swfdec_movie.h
index 17a2f3b..380a32a 100644
--- a/libswfdec/swfdec_movie.h
+++ b/libswfdec/swfdec_movie.h
@@ -134,6 +134,7 @@ struct _SwfdecMovie {
/* drawing state */
/* FIXME: could it be that shape drawing (SwfdecGraphicMovie etc) uses these same objects? */
+ SwfdecImage * image; /* image loaded via loadMovie */
SwfdecRect draw_extents; /* extents of the items in the following list */
GSList * draws; /* all the items to draw */
SwfdecDraw * draw_fill; /* current fill style or NULL */
commit 3cc0c51d81610bcbf081bc9e68b0319d91b7da07
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Nov 12 14:08:49 2007 +0100
create an ImageDecoder for images
diff --git a/libswfdec/swfdec_decoder.c b/libswfdec/swfdec_decoder.c
index 96648e3..24bbda0 100644
--- a/libswfdec/swfdec_decoder.c
+++ b/libswfdec/swfdec_decoder.c
@@ -25,7 +25,8 @@
#include "swfdec_decoder.h"
#include "swfdec_debug.h"
#include "swfdec_decoder.h"
-#include "swfdec_flv_decoder.h"
+#include "swfdec_image.h"
+#include "swfdec_image_decoder.h"
#include "swfdec_swf_decoder.h"
@@ -64,6 +65,8 @@ swfdec_decoder_new (SwfdecPlayer *player, const SwfdecBuffer *buffer)
data[2] == 'V') {
retval = g_object_new (SWFDEC_TYPE_FLV_DECODER, NULL);
#endif
+ } else if (swfdec_image_detect (data) != SWFDEC_IMAGE_TYPE_UNKNOWN) {
+ retval = g_object_new (SWFDEC_TYPE_IMAGE_DECODER, NULL);
} else {
retval = NULL;
}
commit 66e350039483f3a5265df74ee792e51e31f59a8c
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Nov 12 13:15:35 2007 +0100
add ImageDecoder to be able to decode images.
the data type handling needed to be adjusted, too.
diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am
index 69ad762..6aa321f 100644
--- a/libswfdec/Makefile.am
+++ b/libswfdec/Makefile.am
@@ -72,6 +72,7 @@ libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES = \
swfdec_graphic.c \
swfdec_graphic_movie.c \
swfdec_image.c \
+ swfdec_image_decoder.c \
swfdec_interval.c \
swfdec_key_as.c \
swfdec_load_object.c \
@@ -204,6 +205,7 @@ noinst_HEADERS = \
swfdec_graphic.h \
swfdec_graphic_movie.h \
swfdec_image.h \
+ swfdec_image_decoder.h \
swfdec_initialize.h \
swfdec_internal.h \
swfdec_interval.h \
diff --git a/libswfdec/swfdec_decoder.h b/libswfdec/swfdec_decoder.h
index 33f5a5f..7a93276 100644
--- a/libswfdec/swfdec_decoder.h
+++ b/libswfdec/swfdec_decoder.h
@@ -58,6 +58,7 @@ struct _SwfdecDecoder
GObject object;
SwfdecPlayer * player; /* FIXME: only needed to get the JS Context, I want it gone */
+ SwfdecLoaderDataType data_type; /* type of the data we provide or UNKNOWN if not known yet */
guint rate; /* rate per second in 256th */
guint width; /* width of stream */
guint height; /* guess */
diff --git a/libswfdec/swfdec_image_decoder.c b/libswfdec/swfdec_image_decoder.c
new file mode 100644
index 0000000..49443c9
--- /dev/null
+++ b/libswfdec/swfdec_image_decoder.c
@@ -0,0 +1,123 @@
+/* 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 "swfdec_image_decoder.h"
+#include "swfdec_debug.h"
+#include "swfdec_image.h"
+
+G_DEFINE_TYPE (SwfdecImageDecoder, swfdec_image_decoder, SWFDEC_TYPE_DECODER)
+
+static void
+swfdec_image_decoder_dispose (GObject *object)
+{
+ SwfdecImageDecoder *image = SWFDEC_IMAGE_DECODER (object);
+
+ if (image->queue) {
+ swfdec_buffer_queue_unref (image->queue);
+ image->queue = NULL;
+ }
+
+ if (image->image) {
+ g_object_unref (image->image);
+ image->image = NULL;
+ }
+
+ G_OBJECT_CLASS (swfdec_image_decoder_parent_class)->dispose (object);
+}
+
+static SwfdecStatus
+swfdec_image_decoder_parse (SwfdecDecoder *dec, SwfdecBuffer *buffer)
+{
+ SwfdecImageDecoder *image = SWFDEC_IMAGE_DECODER (dec);
+
+ if (image->queue == NULL)
+ image->queue = swfdec_buffer_queue_new ();
+ swfdec_buffer_queue_push (image->queue, buffer);
+ dec->bytes_loaded += buffer->length;
+ if (dec->bytes_loaded < dec->bytes_total)
+ dec->bytes_total = dec->bytes_loaded;
+ return 0;
+}
+
+/* FIXME: move this to swfdec_image API? */
+static gboolean
+swfdec_image_get_size (SwfdecImage *image, guint *w, guint *h)
+{
+ cairo_surface_t *surface;
+
+ surface = swfdec_image_create_surface (image);
+ if (surface == NULL)
+ return FALSE;
+
+ if (w)
+ *w = cairo_image_surface_get_width (surface);
+ if (h)
+ *h = cairo_image_surface_get_width (surface);
+
+ return TRUE;
+}
+
+static SwfdecStatus
+swfdec_image_decoder_eof (SwfdecDecoder *dec)
+{
+ SwfdecImageDecoder *image = SWFDEC_IMAGE_DECODER (dec);
+ SwfdecBuffer *buffer;
+
+ if (image->queue == NULL)
+ return 0;
+ /* FIXME: size checking */
+ buffer = swfdec_buffer_queue_pull (image->queue,
+ swfdec_buffer_queue_get_depth (image->queue));
+ swfdec_buffer_queue_unref (image->queue);
+ image->queue = NULL;
+ image->image = swfdec_image_new (buffer);
+ if (!swfdec_image_get_size (image->image, &dec->width, &dec->height))
+ return SWFDEC_STATUS_ERROR;
+ dec->frames_loaded = 1;
+ dec->frames_total = 1;
+ if (image->image->type == SWFDEC_IMAGE_TYPE_JPEG)
+ dec->data_type = SWFDEC_LOADER_DATA_JPEG;
+ else if (image->image->type == SWFDEC_IMAGE_TYPE_PNG)
+ dec->data_type = SWFDEC_LOADER_DATA_PNG;
+
+
+ return SWFDEC_STATUS_INIT | SWFDEC_STATUS_IMAGE;
+}
+
+static void
+swfdec_image_decoder_class_init (SwfdecImageDecoderClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ SwfdecDecoderClass *decoder_class = SWFDEC_DECODER_CLASS (class);
+
+ object_class->dispose = swfdec_image_decoder_dispose;
+
+ decoder_class->parse = swfdec_image_decoder_parse;
+ decoder_class->eof = swfdec_image_decoder_eof;
+}
+
+static void
+swfdec_image_decoder_init (SwfdecImageDecoder *s)
+{
+}
+
diff --git a/libswfdec/swfdec_image_decoder.h b/libswfdec/swfdec_image_decoder.h
new file mode 100644
index 0000000..b5f3a84
--- /dev/null
+++ b/libswfdec/swfdec_image_decoder.h
@@ -0,0 +1,59 @@
+/* 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
+ */
+
+#ifndef __SWFDEC_IMAGE_DECODER_H__
+#define __SWFDEC_IMAGE_DECODER_H__
+
+#include <glib.h>
+
+#include <libswfdec/swfdec_decoder.h>
+#include <libswfdec/swfdec_bits.h>
+#include <libswfdec/swfdec_types.h>
+#include <libswfdec/swfdec_rect.h>
+
+G_BEGIN_DECLS
+
+typedef struct _SwfdecImageDecoder SwfdecImageDecoder;
+typedef struct _SwfdecImageDecoderClass SwfdecImageDecoderClass;
+
+#define SWFDEC_TYPE_IMAGE_DECODER (swfdec_image_decoder_get_type())
+#define SWFDEC_IS_IMAGE_DECODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_IMAGE_DECODER))
+#define SWFDEC_IS_IMAGE_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_IMAGE_DECODER))
+#define SWFDEC_IMAGE_DECODER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_IMAGE_DECODER, SwfdecImageDecoder))
+#define SWFDEC_IMAGE_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_IMAGE_DECODER, SwfdecImageDecoderClass))
+#define SWFDEC_IMAGE_DECODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_IMAGE_DECODER, SwfdecImageDecoderClass))
+
+struct _SwfdecImageDecoder
+{
+ SwfdecDecoder decoder;
+
+ SwfdecBufferQueue * queue; /* keeps the data while decoding */
+ SwfdecImage * image; /* the image we display */
+};
+
+struct _SwfdecImageDecoderClass {
+ SwfdecDecoderClass decoder_class;
+};
+
+GType swfdec_image_decoder_get_type (void);
+
+
+G_END_DECLS
+
+#endif
diff --git a/libswfdec/swfdec_loader.c b/libswfdec/swfdec_loader.c
index 618b9d7..7595c4e 100644
--- a/libswfdec/swfdec_loader.c
+++ b/libswfdec/swfdec_loader.c
@@ -62,6 +62,8 @@
* @SWFDEC_LOADER_DATA_FLV: Data describing a Flash video stream.
* @SWFDEC_LOADER_DATA_XML: Data in XML format.
* @SWFDEC_LOADER_DATA_TEXT: Textual data.
+ * @SWFDEC_LOADER_DATA_JPEG: a JPEG image
+ * @SWFDEC_LOADER_DATA_PNG: a PNG image
*
* This type describes the different types of data that can be loaded inside
* Swfdec. Swfdec identifies its data streams and you can use the
@@ -577,6 +579,10 @@ swfdec_loader_data_type_get_extension (SwfdecLoaderDataType type)
return "xml";
case SWFDEC_LOADER_DATA_TEXT:
return "txt";
+ case SWFDEC_LOADER_DATA_JPEG:
+ return "jpg";
+ case SWFDEC_LOADER_DATA_PNG:
+ return "png";
default:
g_warning ("unknown data type %u", type);
return "";
diff --git a/libswfdec/swfdec_loader.h b/libswfdec/swfdec_loader.h
index 9eb5b2a..0d0c6a4 100644
--- a/libswfdec/swfdec_loader.h
+++ b/libswfdec/swfdec_loader.h
@@ -31,7 +31,9 @@ typedef enum {
SWFDEC_LOADER_DATA_SWF,
SWFDEC_LOADER_DATA_FLV,
SWFDEC_LOADER_DATA_XML,
- SWFDEC_LOADER_DATA_TEXT
+ SWFDEC_LOADER_DATA_TEXT,
+ SWFDEC_LOADER_DATA_JPEG,
+ SWFDEC_LOADER_DATA_PNG
} SwfdecLoaderDataType;
/* NB: actal numbers in SwfdecLoaderRequest are important for GetURL2 action */
diff --git a/libswfdec/swfdec_resource.c b/libswfdec/swfdec_resource.c
index 00816ca..e24c512 100644
--- a/libswfdec/swfdec_resource.c
+++ b/libswfdec/swfdec_resource.c
@@ -250,11 +250,8 @@ swfdec_resource_loader_target_parse (SwfdecLoaderTarget *target, SwfdecLoader *l
swfdec_buffer_unref (buffer);
if (dec == NULL) {
SWFDEC_ERROR ("no decoder found for format");
- } else if (SWFDEC_IS_SWF_DECODER (dec)) {
- swfdec_loader_set_data_type (loader, SWFDEC_LOADER_DATA_SWF);
- resource->decoder = dec;
} else {
- SWFDEC_FIXME ("implement handling of %s", G_OBJECT_TYPE_NAME (dec));
+ resource->decoder = dec;
}
}
while (swfdec_buffer_queue_get_depth (loader->queue)) {
@@ -308,7 +305,10 @@ swfdec_resource_loader_target_eof (SwfdecLoaderTarget *target, SwfdecLoader *loa
swfdec_resource_emit_signal (resource, SWFDEC_AS_STR_onLoadProgress, TRUE, NULL, 0);
if (resource->decoder) {
- swfdec_decoder_eof (resource->decoder);
+ SwfdecDecoder *dec = resource->decoder;
+ swfdec_decoder_eof (dec);
+ if (dec->data_type != SWFDEC_LOADER_DATA_UNKNOWN)
+ swfdec_loader_set_data_type (loader, dec->data_type);
}
SWFDEC_AS_VALUE_SET_INT (&val, 0); /* FIXME */
movie = swfdec_resource_emit_signal (resource, SWFDEC_AS_STR_onLoadComplete, FALSE, &val, 1);
diff --git a/libswfdec/swfdec_swf_decoder.c b/libswfdec/swfdec_swf_decoder.c
index ae5311c..f079c54 100644
--- a/libswfdec/swfdec_swf_decoder.c
+++ b/libswfdec/swfdec_swf_decoder.c
@@ -234,6 +234,7 @@ swf_parse_header1 (SwfdecSwfDecoder * s)
s->bytes_parsed = 8;
s->state = SWFDEC_STATE_INIT2;
swfdec_swf_decoder_deflate (s, rest);
+ dec->data_type = SWFDEC_LOADER_DATA_SWF;
return SWFDEC_STATUS_OK;
}
commit c4dd05264c289d66d70009cf1bf70905c3878b39
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Nov 12 12:05:10 2007 +0100
split out image type detection
diff --git a/libswfdec/swfdec_image.c b/libswfdec/swfdec_image.c
index a3094c9..661e341 100644
--- a/libswfdec/swfdec_image.c
+++ b/libswfdec/swfdec_image.c
@@ -663,6 +663,21 @@ swfdec_image_create_surface_transformed (SwfdecImage *image, const SwfdecColorTr
return surface;
}
+/* NB: must be at least SWFDEC_DECODER_DETECT_LENGTH bytes */
+SwfdecImageType
+swfdec_image_detect (const guint8 *data)
+{
+ g_return_val_if_fail (data != NULL, SWFDEC_IMAGE_TYPE_UNKNOWN);
+
+ if (data[0] == 0xFF && data[1] == 0xD8)
+ return SWFDEC_IMAGE_TYPE_JPEG2;
+ else if (data[0] == 89 && data[1] == 'P' &&
+ data[2] == 'N' && data[3] == 'G')
+ return SWFDEC_IMAGE_TYPE_PNG;
+ else
+ return SWFDEC_IMAGE_TYPE_UNKNOWN;
+}
+
SwfdecImage *
swfdec_image_new (SwfdecBuffer *buffer)
{
@@ -674,12 +689,8 @@ swfdec_image_new (SwfdecBuffer *buffer)
/* check type of the image */
if (buffer->length < 4)
goto fail;
- if (buffer->data[0] == 0xFF && buffer->data[1] == 0xD8)
- type = SWFDEC_IMAGE_TYPE_JPEG2;
- else if (buffer->data[0] == 89 && buffer->data[1] == 'P' &&
- buffer->data[2] == 'N' && buffer->data[3] == 'G')
- type = SWFDEC_IMAGE_TYPE_PNG;
- else
+ type = swfdec_image_detect (buffer->data);
+ if (type == SWFDEC_IMAGE_TYPE_UNKNOWN)
goto fail;
image = g_object_new (SWFDEC_TYPE_IMAGE, NULL);
diff --git a/libswfdec/swfdec_image.h b/libswfdec/swfdec_image.h
index 9e032ec..e648e08 100644
--- a/libswfdec/swfdec_image.h
+++ b/libswfdec/swfdec_image.h
@@ -66,6 +66,7 @@ struct _SwfdecImageClass {
GType swfdec_image_get_type (void);
+SwfdecImageType swfdec_image_detect (const guint8 * data);
SwfdecImage * swfdec_image_new (SwfdecBuffer * buffer);
cairo_surface_t * swfdec_image_create_surface (SwfdecImage * image);
cairo_surface_t * swfdec_image_create_surface_transformed
commit 96c7c6738613dd92b4c43f9b4daa8871607f07dd
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Nov 12 12:01:20 2007 +0100
call swfdec_decoder_parse()
diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c
index ebd19ba..bb8e8b9 100644
--- a/libswfdec/swfdec_net_stream.c
+++ b/libswfdec/swfdec_net_stream.c
@@ -260,7 +260,6 @@ swfdec_net_stream_loader_target_parse (SwfdecLoaderTarget *target,
SwfdecLoader *loader)
{
SwfdecNetStream *stream = SWFDEC_NET_STREAM (target);
- SwfdecDecoderClass *klass;
SwfdecStatus status;
if (loader->state != SWFDEC_LOADER_STATE_EOF && swfdec_buffer_queue_get_depth (loader->queue) == 0) {
@@ -275,8 +274,6 @@ swfdec_net_stream_loader_target_parse (SwfdecLoaderTarget *target,
SWFDEC_AS_STR_status);
swfdec_loader_set_data_type (loader, SWFDEC_LOADER_DATA_FLV);
}
- klass = SWFDEC_DECODER_GET_CLASS (stream->flvdecoder);
- g_return_if_fail (klass->parse);
status = SWFDEC_STATUS_OK;
do {
@@ -284,7 +281,7 @@ swfdec_net_stream_loader_target_parse (SwfdecLoaderTarget *target,
if (buffer == NULL)
break;
status &= ~SWFDEC_STATUS_NEEDBITS;
- status |= klass->parse (SWFDEC_DECODER (stream->flvdecoder), buffer);
+ status |= swfdec_decoder_parse (SWFDEC_DECODER (stream->flvdecoder), buffer);
} while ((status & (SWFDEC_STATUS_ERROR | SWFDEC_STATUS_EOF)) == 0);
if (status & SWFDEC_STATUS_IMAGE)
commit 2ca365e6a7091ccdac1ed464c6c4d54490a2bfe1
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Nov 12 12:00:25 2007 +0100
add an EOF vfunc to SwfdecDecoder and use it
diff --git a/libswfdec/swfdec_decoder.c b/libswfdec/swfdec_decoder.c
index b17cb98..96648e3 100644
--- a/libswfdec/swfdec_decoder.c
+++ b/libswfdec/swfdec_decoder.c
@@ -86,4 +86,15 @@ swfdec_decoder_parse (SwfdecDecoder *decoder, SwfdecBuffer *buffer)
return klass->parse (decoder, buffer);
}
+SwfdecStatus
+swfdec_decoder_eof (SwfdecDecoder *decoder)
+{
+ SwfdecDecoderClass *klass;
+
+ g_return_val_if_fail (SWFDEC_IS_DECODER (decoder), SWFDEC_STATUS_ERROR);
+
+ klass = SWFDEC_DECODER_GET_CLASS (decoder);
+ g_return_val_if_fail (klass->eof, SWFDEC_STATUS_ERROR);
+ return klass->eof (decoder);
+}
diff --git a/libswfdec/swfdec_decoder.h b/libswfdec/swfdec_decoder.h
index 7483df1..33f5a5f 100644
--- a/libswfdec/swfdec_decoder.h
+++ b/libswfdec/swfdec_decoder.h
@@ -73,6 +73,7 @@ struct _SwfdecDecoderClass
SwfdecStatus (* parse) (SwfdecDecoder * decoder,
SwfdecBuffer * buffer);
+ SwfdecStatus (* eof) (SwfdecDecoder * decoder);
};
GType swfdec_decoder_get_type (void);
@@ -83,6 +84,7 @@ SwfdecDecoder * swfdec_decoder_new (SwfdecPlayer * player,
SwfdecStatus swfdec_decoder_parse (SwfdecDecoder * decoder,
SwfdecBuffer * buffer);
+SwfdecStatus swfdec_decoder_eof (SwfdecDecoder * decoder);
G_END_DECLS
diff --git a/libswfdec/swfdec_flv_decoder.c b/libswfdec/swfdec_flv_decoder.c
index 465852d..8caf2b6 100644
--- a/libswfdec/swfdec_flv_decoder.c
+++ b/libswfdec/swfdec_flv_decoder.c
@@ -433,6 +433,16 @@ swfdec_flv_decoder_parse (SwfdecDecoder *dec, SwfdecBuffer *buffer)
return status;
}
+static SwfdecStatus
+swfdec_flv_decoder_eof (SwfdecDecoder *dec)
+{
+ SwfdecFlvDecoder *flv = SWFDEC_FLV_DECODER (dec);
+
+ flv->state = SWFDEC_STATE_EOF;
+
+ return 0;
+}
+
static void
swfdec_flv_decoder_class_init (SwfdecFlvDecoderClass *class)
{
@@ -442,6 +452,7 @@ swfdec_flv_decoder_class_init (SwfdecFlvDecoderClass *class)
object_class->dispose = swfdec_flv_decoder_dispose;
decoder_class->parse = swfdec_flv_decoder_parse;
+ decoder_class->eof = swfdec_flv_decoder_eof;
}
static void
@@ -602,11 +613,3 @@ swfdec_flv_decoder_is_eof (SwfdecFlvDecoder *flv)
return flv->state == SWFDEC_STATE_EOF;
}
-void
-swfdec_flv_decoder_eof (SwfdecFlvDecoder *flv)
-{
- g_return_if_fail (SWFDEC_IS_FLV_DECODER (flv));
-
- flv->state = SWFDEC_STATE_EOF;
-}
-
diff --git a/libswfdec/swfdec_flv_decoder.h b/libswfdec/swfdec_flv_decoder.h
index 5ad5114..635fea4 100644
--- a/libswfdec/swfdec_flv_decoder.h
+++ b/libswfdec/swfdec_flv_decoder.h
@@ -56,7 +56,6 @@ struct _SwfdecFlvDecoderClass {
GType swfdec_flv_decoder_get_type (void);
gboolean swfdec_flv_decoder_is_eof (SwfdecFlvDecoder * flv);
-void swfdec_flv_decoder_eof (SwfdecFlvDecoder * flv);
SwfdecBuffer * swfdec_flv_decoder_get_video (SwfdecFlvDecoder * flv,
guint timestamp,
diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c
index 93493ca..ebd19ba 100644
--- a/libswfdec/swfdec_net_stream.c
+++ b/libswfdec/swfdec_net_stream.c
@@ -298,7 +298,7 @@ swfdec_net_stream_loader_target_eof (SwfdecLoaderTarget *target,
SwfdecNetStream *stream = SWFDEC_NET_STREAM (target);
guint first, last;
- swfdec_flv_decoder_eof (stream->flvdecoder);
+ swfdec_decoder_eof (SWFDEC_DECODER (stream->flvdecoder));
swfdec_net_stream_onstatus (stream, SWFDEC_AS_STR_NetStream_Buffer_Flush,
SWFDEC_AS_STR_status);
swfdec_net_stream_video_goto (stream, stream->current_time);
diff --git a/libswfdec/swfdec_resource.c b/libswfdec/swfdec_resource.c
index c93d151..00816ca 100644
--- a/libswfdec/swfdec_resource.c
+++ b/libswfdec/swfdec_resource.c
@@ -307,6 +307,9 @@ swfdec_resource_loader_target_eof (SwfdecLoaderTarget *target, SwfdecLoader *loa
SwfdecSpriteMovie *movie;
swfdec_resource_emit_signal (resource, SWFDEC_AS_STR_onLoadProgress, TRUE, NULL, 0);
+ if (resource->decoder) {
+ swfdec_decoder_eof (resource->decoder);
+ }
SWFDEC_AS_VALUE_SET_INT (&val, 0); /* FIXME */
movie = swfdec_resource_emit_signal (resource, SWFDEC_AS_STR_onLoadComplete, FALSE, &val, 1);
/* FIXME: I bet this is wrong for figuring out if movies should emit onLoadInit */
diff --git a/libswfdec/swfdec_swf_decoder.c b/libswfdec/swfdec_swf_decoder.c
index 4a9b069..ae5311c 100644
--- a/libswfdec/swfdec_swf_decoder.c
+++ b/libswfdec/swfdec_swf_decoder.c
@@ -387,6 +387,17 @@ swfdec_swf_decoder_parse (SwfdecDecoder *dec, SwfdecBuffer *buffer)
return status;
}
+static SwfdecStatus
+swfdec_swf_decoder_eof (SwfdecDecoder *dec)
+{
+ if (dec->bytes_loaded < dec->bytes_total) {
+ SWFDEC_ERROR ("only %u of %u bytes provided, broken transmission?",
+ dec->bytes_loaded, dec->bytes_total);
+ }
+
+ return 0;
+}
+
static void
swfdec_swf_decoder_class_init (SwfdecSwfDecoderClass *class)
{
@@ -396,6 +407,7 @@ swfdec_swf_decoder_class_init (SwfdecSwfDecoderClass *class)
object_class->dispose = swfdec_swf_decoder_dispose;
decoder_class->parse = swfdec_swf_decoder_parse;
+ decoder_class->eof = swfdec_swf_decoder_eof;
}
static void
commit d3da8c049e6bf4f8accb6811ffdf694a3c02f698
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Nov 12 11:44:44 2007 +0100
add missing image enum type
diff --git a/test/dump.c b/test/dump.c
index 254a19c..56a270d 100644
--- a/test/dump.c
+++ b/test/dump.c
@@ -316,6 +316,8 @@ get_image_type_name (SwfdecImageType type)
return "lossless";
case SWFDEC_IMAGE_TYPE_LOSSLESS2:
return "lossless with alpha";
+ case SWFDEC_IMAGE_TYPE_PNG:
+ return "PNG";
case SWFDEC_IMAGE_TYPE_UNKNOWN:
default:
g_assert_not_reached ();
commit 961c2949677b75767ee892a6140f41fa812d5c8e
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Nov 12 10:47:33 2007 +0100
data might be used uninitialized
Also, it's nice to throw an error about unkown formats
diff --git a/libswfdec/swfdec_image.c b/libswfdec/swfdec_image.c
index 0d0362d..a3094c9 100644
--- a/libswfdec/swfdec_image.c
+++ b/libswfdec/swfdec_image.c
@@ -448,8 +448,7 @@ swfdec_image_lossless_load (SwfdecImage *image)
ptr += 2;
}
swfdec_buffer_unref (buffer);
- }
- if (format == 5) {
+ } else if (format == 5) {
SwfdecBuffer *buffer;
int i, j;
buffer = swfdec_bits_decompress (&bits, -1, 4 * image->width * image->height);
@@ -471,6 +470,9 @@ swfdec_image_lossless_load (SwfdecImage *image)
buffer->data = NULL;
buffer->length = 0;
swfdec_buffer_unref (buffer);
+ } else {
+ SWFDEC_ERROR ("unknwon lossless image format %u", format);
+ return;
}
out:
@@ -674,8 +676,8 @@ swfdec_image_new (SwfdecBuffer *buffer)
goto fail;
if (buffer->data[0] == 0xFF && buffer->data[1] == 0xD8)
type = SWFDEC_IMAGE_TYPE_JPEG2;
- else if (buffer->data[0] == 0xFF && buffer->data[1] == 0xD8 &&
- buffer->data[0] == 0xFF && buffer->data[1] == 0xD8)
+ else if (buffer->data[0] == 89 && buffer->data[1] == 'P' &&
+ buffer->data[2] == 'N' && buffer->data[3] == 'G')
type = SWFDEC_IMAGE_TYPE_PNG;
else
goto fail;
More information about the Swfdec
mailing list