Benjamin Otte
2007-Nov-12 17:24 UTC
[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
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;
Seemingly Similar Threads
- 7 commits - doc/swfdec-sections.txt libswfdec-gtk/swfdec_gtk_widget.c libswfdec/swfdec_as_strings.c libswfdec/swfdec_decoder.c libswfdec/swfdec_flv_decoder.c libswfdec/swfdec_movie_asprops.c libswfdec/swfdec_net_stream.c libswfdec/swfdec_player.c
- 6 commits - libswfdec/Makefile.am libswfdec/swfdec_as_interpret.c libswfdec/swfdec_color_as.c libswfdec/swfdec_graphic_movie.c libswfdec/swfdec_image_decoder.c libswfdec/swfdec_morph_movie.c libswfdec/swfdec_movie_as_drawing.c
- 36 commits - doc/swfdec-sections.txt libswfdec/Makefile.am libswfdec/swfdec_amf.c libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_object.c libswfdec/swfdec_as_object.h libswfdec/swfdec_as_strings.c libswfdec/swfdec_buffer.c libswfdec/swfdec_buffer.h
- 5 commits - libswfdec/swfdec_net_stream.c libswfdec/swfdec_player.c libswfdec/swfdec_resource.c libswfdec/swfdec_resource.h player/swfdec_slow_loader.c test/trace
- 2 commits - doc/Makefile.am doc/swfdec-sections.txt NEWS