Benjamin Otte
2008-Jan-07 18:39 UTC
[Swfdec] 12 commits - configure.ac doc/swfdec.types Makefile.am test/crashfinder.c test/dump.c test/Makefile.am test/swfdec-extract.c test/swfdec_out.c test/swfdec_out.h test/swfedit.c test/swfedit_file.c test/swfedit_file.h test/swfedit_list.c test/swfedit_list.h test/swfedit_tag.c test/swfedit_tag.h test/swfedit_token.c test/swfedit_token.h test/swfscript.c test/test tools/crashfinder.c tools/dump.c tools/.gitignore tools/Makefile.am tools/swfdec-extract.c tools/swfdec_out.c tools/swfdec_out.h tools/swfedit.c tools/swfedit_file.c tools/swfedit_file.h tools/swfedit_list.c tools/swfedit_list.h tools/swfedit_tag.c tools/swfedit_tag.h tools/swfedit_token.c tools/swfedit_token.h tools/swfscript.c vivified/core
Makefile.am | 3 configure.ac | 2 doc/swfdec.types | 8 test/Makefile.am | 45 -- test/crashfinder.c | 157 ------- test/dump.c | 448 -------------------- test/swfdec-extract.c | 301 ------------- test/swfdec_out.c | 383 ----------------- test/swfdec_out.h | 88 --- test/swfedit.c | 138 ------ test/swfedit_file.c | 297 ------------- test/swfedit_file.h | 60 -- test/swfedit_list.c | 149 ------ test/swfedit_list.h | 61 -- test/swfedit_tag.c | 507 ---------------------- test/swfedit_tag.h | 83 --- test/swfedit_token.c | 797 ------------------------------------ test/swfedit_token.h | 109 ---- test/swfscript.c | 298 ------------- test/test/.gitignore | 4 test/test/Makefile.am | 31 + test/test/compiler.c | 57 ++ test/test/swfdec_test.c | 141 ++++++ test/test/swfdec_test_function.c | 67 +++ test/test/swfdec_test_function.h | 35 + test/test/swfdec_test_global.c | 40 + test/test/swfdec_test_initialize.as | 34 + test/test/swfdec_test_initialize.h | 32 + test/test/swfdec_test_test.c | 262 +++++++++++ test/test/swfdec_test_test.h | 62 ++ tools/.gitignore | 17 tools/Makefile.am | 41 + tools/crashfinder.c | 157 +++++++ tools/dump.c | 448 ++++++++++++++++++++ tools/swfdec-extract.c | 301 +++++++++++++ tools/swfdec_out.c | 383 +++++++++++++++++ tools/swfdec_out.h | 88 +++ tools/swfedit.c | 138 ++++++ tools/swfedit_file.c | 297 +++++++++++++ tools/swfedit_file.h | 60 ++ tools/swfedit_list.c | 149 ++++++ tools/swfedit_list.h | 61 ++ tools/swfedit_tag.c | 507 ++++++++++++++++++++++ tools/swfedit_tag.h | 83 +++ tools/swfedit_token.c | 797 ++++++++++++++++++++++++++++++++++++ tools/swfedit_token.h | 109 ++++ tools/swfscript.c | 298 +++++++++++++ vivified/core/Makefile.am | 2 48 files changed, 4712 insertions(+), 3923 deletions(-) New commits: commit abfc9954a36911aabc29ca2252628e7925287757 Author: Benjamin Otte <otte at gnome.org> Date: Mon Jan 7 19:38:36 2008 +0100 move tools from test/ to tools/ diff --git a/Makefile.am b/Makefile.am index 0c33e5c..d13fae6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -18,7 +18,8 @@ SUBDIRS= \ $(GTK_SUBDIRS) \ $(VIVI_SUBDIRS) \ data \ - test + test \ + tools ACLOCAL_FLAGS = -I m4 diff --git a/configure.ac b/configure.ac index 98d756a..338ca51 100644 --- a/configure.ac +++ b/configure.ac @@ -357,6 +357,7 @@ test/sound/Makefile test/test/Makefile test/trace/Makefile test/various/Makefile +tools/Makefile vivified/Makefile vivified/core/Makefile vivified/dock/Makefile diff --git a/test/Makefile.am b/test/Makefile.am index d69a082..c8cbfbc 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,44 +1 @@ SUBDIRS = image sound test trace various - - -if WITH_GTK -noinst_LTLIBRARIES = libswfedit.la -noinst_PROGRAMS = swfdec-extract dump swfedit swfscript crashfinder -else -noinst_PROGRAMS = swfdec-extract dump crashfinder -endif - -crashfinder_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) -crashfinder_LDFLAGS = $(SWFDEC_LIBS) $(CAIRO_LIBS) -crashfinder_SOURCES = crashfinder.c - -dump_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(CAIRO_CFLAGS) $(PANGO_CFLAGS) -dump_LDFLAGS = $(SWFDEC_LIBS) $(CAIRO_LIBS) $(PANGO_LIBS) - -swfdec_extract_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(CAIRO_CFLAGS) -swfdec_extract_LDFLAGS = $(SWFDEC_LIBS) $(CAIRO_LIBS) - -libswfedit_la_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(GTK_CFLAGS) -libswfedit_la_LDFLAGS = $(SWFDEC_LIBS) $(GTK_LIBS) - -swfedit_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(GTK_CFLAGS) -swfedit_LDFLAGS = $(SWFDEC_LIBS) $(GTK_LIBS) -swfedit_LDADD = libswfedit.la - -swfscript_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(GTK_CFLAGS) -swfscript_LDFLAGS = $(SWFDEC_LIBS) $(GTK_LIBS) -swfscript_LDADD = libswfedit.la - -libswfedit_la_SOURCES = \ - swfdec_out.c \ - swfedit_file.c \ - swfedit_list.c \ - swfedit_tag.c \ - swfedit_token.c - -noinst_HEADERS = \ - swfdec_out.h \ - swfedit_file.h \ - swfedit_list.h \ - swfedit_tag.h \ - swfedit_token.h diff --git a/test/crashfinder.c b/test/crashfinder.c deleted file mode 100644 index 3c4a4a7..0000000 --- a/test/crashfinder.c +++ /dev/null @@ -1,157 +0,0 @@ -/* Swfdec - * Copyright (C) 2007 Pekka Lampila <pekka.lampila at iki.fi> - * 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 <libswfdec/swfdec.h> - -int -main (int argc, char **argv) -{ - GOptionContext *context; - GError *err; - SwfdecPlayer *player; - SwfdecLoader *loader; - guint i; - cairo_surface_t *surface; - cairo_t *cr; - gboolean aborts; - glong play_per_file = 30; - glong max_per_file = 60; - glong max_per_advance = 10; - GTimer *timer; - char **filenames = NULL; - const GOptionEntry entries[] = { - { - "play-time", 'p', 0, G_OPTION_ARG_INT, &play_per_file, - "How many seconds will be played from each file (default 30)", NULL - }, - { - "max-per-file", '\0', 0, G_OPTION_ARG_INT, &max_per_file, - "Maximum runtime in seconds allowed for each file (default 60)", NULL - }, - { - "max-per-advance", '\0', 0, G_OPTION_ARG_INT, &max_per_advance, - "Maximum runtime in seconds allowed for each advance (default 10)", NULL - }, - { - G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, - NULL, "<INPUT FILE> <OUTPUT FILE>" - }, - { - NULL - } - }; - - // init - swfdec_init (); - - // read command line params - context = g_option_context_new ("Run a Flash file trying to crash Swfdec"); - g_option_context_add_main_entries (context, entries, NULL); - - if (g_option_context_parse (context, &argc, &argv, &err) == FALSE) { - g_printerr ("Couldn't parse command-line options: %s\n", err->message); - g_error_free (err); - return 1; - } - - if (filenames == NULL || g_strv_length (filenames) < 1) { - g_printerr ("At least one input filename is required\n"); - return 1; - } - - // make them milliseconds - play_per_file *= 1000; - max_per_file *= 1000; - max_per_advance *= 1000; - - // create surface - surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1); - cr = cairo_create (surface); - - aborts = FALSE; - for (i = 0; i < g_strv_length (filenames); i++) - { - glong played, advance, elapsed; - - g_print ("Running: %s\n", filenames[i]); - - // start timer - timer = g_timer_new (); - - // create player - loader = swfdec_file_loader_new (filenames[i]); - player = swfdec_player_new (NULL); - - if (loader->error) { - g_printerr ("Error loading %s: %s\n", filenames[i], loader->error); - g_object_unref (loader); - continue; - } - - swfdec_player_set_loader (player, loader); - - // loop until we have played what we wanted, or timelimit is hit - played = 0; - elapsed = 0; - while (played < play_per_file && - !swfdec_as_context_is_aborted (SWFDEC_AS_CONTEXT (player))) - { - elapsed = (glong)(g_timer_elapsed (timer, NULL) * 1000); - if (elapsed >= max_per_file) - break; - swfdec_player_set_maximum_runtime (player, - MIN (max_per_advance, max_per_file - elapsed)); - - advance = swfdec_player_get_next_event (player); - if (advance == -1) - break; - swfdec_player_advance (player, advance); - - swfdec_player_render (player, cr, 0, 0, 0, 0); - - played += advance; - } - - if (elapsed >= max_per_file || - swfdec_as_context_is_aborted (SWFDEC_AS_CONTEXT (player))) { - g_print ("Aborted: %s\n", filenames[i]); - aborts = TRUE; - } else { - g_print ("Finished: %s\n", filenames[i]); - } - - // clean up - g_object_unref (player); - g_timer_destroy (timer); - } - - cairo_destroy (cr); - cairo_surface_destroy (surface); - - if (aborts) { - return 1; - } else { - return 0; - } -} diff --git a/test/dump.c b/test/dump.c deleted file mode 100644 index efea56d..0000000 --- a/test/dump.c +++ /dev/null @@ -1,448 +0,0 @@ -/* Swfdec - * Copyright (C) 2003-2006 David Schleef <ds at schleef.org> - * 2005-2006 Eric Anholt <eric at anholt.net> - * 2006-2007 Benjamin Otte <otte at gnome.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * 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 <stdio.h> -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <sys/stat.h> -#include <glib.h> -#include <glib-object.h> -#include <libswfdec/swfdec.h> -#include <libswfdec/swfdec_button.h> -#include <libswfdec/swfdec_text_field.h> -#include <libswfdec/swfdec_font.h> -#include <libswfdec/swfdec_image.h> -#include <libswfdec/swfdec_movie.h> -#include <libswfdec/swfdec_player_internal.h> -#include <libswfdec/swfdec_sprite.h> -#include <libswfdec/swfdec_shape.h> -#include <libswfdec/swfdec_sound.h> -#include <libswfdec/swfdec_swf_decoder.h> -#include <libswfdec/swfdec_resource.h> -#include <libswfdec/swfdec_tag.h> -#include <libswfdec/swfdec_text.h> - -static gboolean verbose = FALSE; - -static const char * -get_audio_format_name (guint codec) -{ - switch (codec) { - case SWFDEC_AUDIO_CODEC_ADPCM: - return "ADPCM"; - case SWFDEC_AUDIO_CODEC_MP3: - return "MP3"; - case SWFDEC_AUDIO_CODEC_UNCOMPRESSED: - return "uncompressed"; - case SWFDEC_AUDIO_CODEC_NELLYMOSER: - return "Nellymoser"; - default: - return "Unknown"; - } -} - -static void -dump_sound (SwfdecSound *sound) -{ - g_print (" codec: %s\n", get_audio_format_name (sound->codec)); - if (verbose) { - g_print (" format: %s\n", swfdec_audio_format_to_string (sound->format)); - g_print (" samples: %u (%gs)\n", sound->n_samples, - (double) sound->n_samples / swfdec_audio_format_get_rate (sound->format)); - } -} - -static void -dump_sprite (SwfdecSwfDecoder *dec, SwfdecSprite *s) -{ - if (!verbose) { - g_print (" %u frames\n", s->n_frames); - } else { - guint i, j, tag; - SwfdecBuffer *buffer; - SwfdecSound *sound = NULL; - - for (i = 0; i < s->n_frames; i++) { - SwfdecSpriteFrame *frame = &s->frames[i]; - if (frame->sound_head != sound && - frame->sound_block != NULL) { - sound = frame->sound_head; - for (j = i; j < s->n_frames; j++) { - SwfdecSpriteFrame *cur = &s->frames[i]; - if (cur->sound_head != sound) - break; - } - if (sound) - g_print (" %4u -%4u sound: %s %s\n", i, j, - get_audio_format_name (sound->codec), - swfdec_audio_format_to_string (sound->format)); - } - } - - j = 0; - for (i = 0; ; i++) { - if (!swfdec_sprite_get_action (s, i, &tag, &buffer)) - break; - switch (tag) { - case SWFDEC_TAG_DOACTION: - g_print (" %4u script\n", j); - break; - case SWFDEC_TAG_PLACEOBJECT2: - case SWFDEC_TAG_PLACEOBJECT3: - { - SwfdecBits bits; - gboolean has_char, is_move; - guint depth; - - swfdec_bits_init (&bits, buffer); - swfdec_bits_getbits (&bits, 6); - has_char = swfdec_bits_getbit (&bits); - is_move = swfdec_bits_getbit (&bits); - if (tag == SWFDEC_TAG_PLACEOBJECT3) - swfdec_bits_get_u8 (&bits); - depth = swfdec_bits_get_u16 (&bits); - g_print (" %4u %5u %s", j, depth, is_move ? "move" : "place"); - if (has_char) { - SwfdecCharacter *c; - c = swfdec_swf_decoder_get_character (dec, swfdec_bits_get_u16 (&bits)); - if (c) - g_print (" %s %u", G_OBJECT_TYPE_NAME (c), c->id); - } - g_print ("\n"); - } - break; - case SWFDEC_TAG_REMOVEOBJECT: - case SWFDEC_TAG_REMOVEOBJECT2: - { - SwfdecBits bits; - swfdec_bits_init (&bits, buffer); - if (tag == SWFDEC_TAG_REMOVEOBJECT) - swfdec_bits_get_u16 (&bits); - g_print (" %4u %5u remove\n", j, swfdec_bits_get_u16 (&bits)); - } - break; - case SWFDEC_TAG_SHOWFRAME: - j++; - break; - case SWFDEC_TAG_STARTSOUND: - /* FIXME add info about what sound etc */ - g_print (" %4u start sound\n", j); - break; - case SWFDEC_TAG_EXPORTASSETS: - g_print (" %4u export\n", j); - break; - case SWFDEC_TAG_DOINITACTION: - g_print (" %4u init action\n", j); - break; - default: - g_assert_not_reached (); - } - } - } -} - -static void -dump_path (cairo_path_t *path) -{ - int i; - cairo_path_data_t *data = path->data; - const char *name; - - for (i = 0; i < path->num_data; i++) { - name = NULL; - switch (data[i].header.type) { - case CAIRO_PATH_CURVE_TO: - g_print (" curve %g %g (%g %g . %g %g)\n", - data[i + 3].point.x, data[i + 3].point.y, - data[i + 1].point.x, data[i + 1].point.y, - data[i + 2].point.x, data[i + 2].point.y); - i += 3; - break; - case CAIRO_PATH_LINE_TO: - name = "line "; - case CAIRO_PATH_MOVE_TO: - if (!name) - name = "move "; - i++; - g_print (" %s %g %g\n", name, data[i].point.x, data[i].point.y); - break; - case CAIRO_PATH_CLOSE_PATH: - g_print (" close\n"); - break; - default: - g_assert_not_reached (); - break; - } - } -} - -static void -dump_shape (SwfdecShape *shape) -{ - GSList *walk; - - for (walk = shape->draws; walk; walk = walk->next) { - if (SWFDEC_IS_PATTERN (walk->data)) { - SwfdecPattern *pattern = walk->data; - char *str = swfdec_pattern_to_string (pattern); - g_print ("%s\n", str); - g_free (str); - if (verbose) { - g_print (" %g %g %g %g %g %g\n", - pattern->start_transform.xx, pattern->start_transform.xy, - pattern->start_transform.yx, pattern->start_transform.yy, - pattern->start_transform.x0, pattern->start_transform.y0); - } - } else if (SWFDEC_IS_STROKE (walk->data)) { - SwfdecStroke *line = walk->data; - g_print ("line (width %u, color #%08X)\n", line->start_width, line->start_color); - } else { - g_print ("not filled\n"); - } - if (verbose) { - dump_path (&SWFDEC_DRAW (walk->data)->path); - } - } -} - -static void -dump_text_field (SwfdecTextField *text) -{ - g_print (" %s\n", text->input ? text->input : ""); - if (verbose) { - if (text->variable) - g_print (" variable %s\n", text->variable); - else - g_print (" no variable\n"); - } -} - -static void -dump_text (SwfdecText *text) -{ - guint i; - gunichar2 uni[text->glyphs->len]; - char *s; - - for (i = 0; i < text->glyphs->len; i++) { - SwfdecTextGlyph *glyph = &g_array_index (text->glyphs, SwfdecTextGlyph, i); - uni[i] = g_array_index (glyph->font->glyphs, SwfdecFontEntry, glyph->glyph).value; - if (uni[i] == 0) - goto fallback; - } - s = g_utf16_to_utf8 (uni, text->glyphs->len, NULL, NULL, NULL); - if (s == NULL) - goto fallback; - g_print (" text: %s\n", s); - g_free (s); - return; - -fallback: - g_print (" %u characters\n", text->glyphs->len); -} - -static void -dump_font (SwfdecFont *font) -{ - unsigned int i; - if (font->name) - g_print (" %s\n", font->name); - g_print (" %u characters\n", font->glyphs->len); - if (verbose) { - for (i = 0; i < font->glyphs->len; i++) { - gunichar2 c = g_array_index (font->glyphs, SwfdecFontEntry, i).value; - char *s; - if (c == 0 || (s = g_utf16_to_utf8 (&c, 1, NULL, NULL, NULL)) == NULL) { - g_print (" "); - } else { - g_print ("%s ", s); - g_free (s); - } - } - g_print ("\n"); - } -} - -static void -dump_button (SwfdecButton *button) -{ -} - -static const char * -get_image_type_name (SwfdecImageType type) -{ - switch (type) { - case SWFDEC_IMAGE_TYPE_JPEG: - return "JPEG with global table"; - case SWFDEC_IMAGE_TYPE_JPEG2: - return "JPEG"; - case SWFDEC_IMAGE_TYPE_JPEG3: - return "JPEG with alpha"; - case SWFDEC_IMAGE_TYPE_LOSSLESS: - 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 (); - return "Unknown"; - } -} - -static void -dump_image (SwfdecImage *image) -{ - cairo_surface_destroy (swfdec_image_create_surface (image)); - g_print (" %s %u x %u\n", get_image_type_name (image->type), - image->width, image->height); -} - -static void -dump_object (gpointer value, gpointer dec) -{ - SwfdecCharacter *c = value; - - g_print ("%d: %s\n", c->id, G_OBJECT_TYPE_NAME (c)); - if (verbose && SWFDEC_IS_GRAPHIC (c)) { - SwfdecGraphic *graphic = SWFDEC_GRAPHIC (c); - g_print (" extents: %g %g %g %g\n", graphic->extents.x0, graphic->extents.y0, - graphic->extents.x1, graphic->extents.y1); - } - if (SWFDEC_IS_IMAGE (c)) { - dump_image (SWFDEC_IMAGE (c)); - } - if (SWFDEC_IS_SPRITE (c)) { - dump_sprite (dec, SWFDEC_SPRITE (c)); - } - if (SWFDEC_IS_SHAPE(c)) { - dump_shape(SWFDEC_SHAPE(c)); - } - if (SWFDEC_IS_TEXT (c)) { - dump_text (SWFDEC_TEXT (c)); - } - if (SWFDEC_IS_TEXT_FIELD (c)) { - dump_text_field (SWFDEC_TEXT_FIELD (c)); - } - if (SWFDEC_IS_FONT (c)) { - dump_font (SWFDEC_FONT (c)); - } - if (SWFDEC_IS_BUTTON (c)) { - dump_button (SWFDEC_BUTTON (c)); - } - if (SWFDEC_IS_SOUND (c)) { - dump_sound (SWFDEC_SOUND (c)); - } -} - -static void -enqueue (gpointer key, gpointer value, gpointer listp) -{ - GList **list = listp; - - *list = g_list_prepend (*list, value); -} - -static int -sort_by_id (gconstpointer a, gconstpointer b) -{ - if (SWFDEC_CHARACTER (a)->id < SWFDEC_CHARACTER (b)->id) - return -1; - return 1; -} - -int -main (int argc, char *argv[]) -{ - SwfdecSwfDecoder *s; - SwfdecPlayer *player; - GError *error = NULL; - GOptionEntry options[] = { - { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "bew verbose", NULL }, - { NULL } - }; - GOptionContext *ctx; - GList *list = NULL; - - ctx = g_option_context_new (""); - g_option_context_add_main_entries (ctx, options, "options"); - g_option_context_parse (ctx, &argc, &argv, &error); - g_option_context_free (ctx); - if (error) { - g_printerr ("Error parsing command line arguments: %s\n", error->message); - g_error_free (error); - return 1; - } - - swfdec_init(); - - if(argc < 2){ - g_print ("usage: %s [OPTIONS] file\n", argv[0]); - return 0; - } - - player = swfdec_player_new_from_file (argv[1]); - if (player->priv->resource->loader->error) { - g_printerr ("Couldn't open file \"%s\": %s\n", argv[1], player->priv->resource->loader->error); - g_object_unref (player); - return 1; - } - /* FIXME: HACK! */ - swfdec_player_advance (player, 0); - if (!swfdec_player_is_initialized (player)) { - g_printerr ("File \"%s\" is not a SWF file\n", argv[1]); - g_object_unref (player); - player = NULL; - return 1; - } - s = (SwfdecSwfDecoder *) SWFDEC_MOVIE (player->priv->roots->data)->resource->decoder; - /* FIXME: can happen after a _root.loadMovie() call */ - if (!SWFDEC_IS_SWF_DECODER (s)) { - g_printerr ("Movie already unloaded from \"%s\"\n", argv[1]); - g_object_unref (player); - player = NULL; - return 1; - } - - g_print ("file:\n"); - g_print (" version: %d\n", s->version); - g_print (" rate : %g fps\n", SWFDEC_DECODER (s)->rate / 256.0); - g_print (" size : %ux%u pixels\n", SWFDEC_DECODER (s)->width, SWFDEC_DECODER (s)->height); - g_print ("objects:\n"); - g_hash_table_foreach (s->characters, enqueue, &list); - list = g_list_sort (list, sort_by_id); - g_list_foreach (list, dump_object, s); - g_list_free (list); - - g_print ("main sprite:\n"); - dump_sprite (s, s->main_sprite); - g_object_unref (player); - s = NULL; - player = NULL; - - return 0; -} - diff --git a/test/swfdec-extract.c b/test/swfdec-extract.c deleted file mode 100644 index 3edfd25..0000000 --- a/test/swfdec-extract.c +++ /dev/null @@ -1,301 +0,0 @@ -/* Swfdec - * Copyright (C) 2006 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 <math.h> -#include <stdlib.h> -#include <string.h> -#include <cairo.h> -#ifdef CAIRO_HAS_SVG_SURFACE -# include <cairo-svg.h> -#endif -#ifdef CAIRO_HAS_PDF_SURFACE -# include <cairo-pdf.h> -#endif -#include <libswfdec/swfdec.h> -#include <libswfdec/swfdec_audio_stream.h> -#include <libswfdec/swfdec_button.h> -#include <libswfdec/swfdec_graphic.h> -#include <libswfdec/swfdec_image.h> -#include <libswfdec/swfdec_player_internal.h> -#include <libswfdec/swfdec_sound.h> -#include <libswfdec/swfdec_sprite.h> -#include <libswfdec/swfdec_sprite_movie.h> -#include <libswfdec/swfdec_swf_decoder.h> -#include <libswfdec/swfdec_resource.h> - -static SwfdecBuffer * -encode_wav (SwfdecBuffer *buffer, SwfdecAudioFormat format) -{ - SwfdecBuffer *wav = swfdec_buffer_new_and_alloc (buffer->length + 44); - unsigned char *data; - guint i; - - data = wav->data; - /* FIXME: too much magic in this memmove */ - memmove (data, "RIFF----WAVEfmt \020\0\0\0" - "\001\0ccRRRRbbbbAAbbdata", 40); - *(guint32 *) (void *) &data[4] = GUINT32_TO_LE (buffer->length + 36); - *(guint16 *) (void *) &data[22] = GUINT16_TO_LE (swfdec_audio_format_get_channels (format)); - *(guint32 *) (void *) &data[24] = GUINT32_TO_LE (swfdec_audio_format_get_rate (format)); - /* bits per sample */ - i = swfdec_audio_format_is_16bit (format) ? 2 : 1; - *(guint16 *) (void *) &data[34] = GUINT16_TO_LE (i * 8); - /* block align */ - i *= swfdec_audio_format_get_channels (format); - *(guint16 *) (void *) &data[32] = GUINT16_TO_LE (i); - /* bytes per second */ - i *= swfdec_audio_format_get_rate (format); - *(guint32 *) (void *) &data[28] = GUINT32_TO_LE (i); - *(guint32 *) (void *) &data[40] = GUINT32_TO_LE (buffer->length); - data += 44; - if (swfdec_audio_format_is_16bit (format)) { - for (i = 0; i < buffer->length; i += 2) { - *(gint16 *) (void *) (data + i) = GINT16_TO_LE (*(gint16* ) (void *) (buffer->data + i)); - } - } else { - memcpy (data, buffer->data, buffer->length); - } - return wav; -} - -static gboolean -export_sound (SwfdecSound *sound, const char *filename) -{ - GError *error = NULL; - SwfdecBuffer *wav, *buffer; - SwfdecAudioFormat format; - - /* try to render the sound, that should decode it. */ - buffer = swfdec_sound_get_decoded (sound, &format); - if (buffer == NULL) { - g_printerr ("Couldn't decode sound. For extraction of streams extract the sprite.\n"); - return FALSE; - } - wav = encode_wav (buffer, format); - if (!g_file_set_contents (filename, (char *) wav->data, - wav->length, &error)) { - g_printerr ("Couldn't save sound to file \"%s\": %s\n", filename, error->message); - swfdec_buffer_unref (wav); - g_error_free (error); - return FALSE; - } - swfdec_buffer_unref (wav); - return TRUE; -} - -static gboolean -export_sprite_sound (SwfdecSprite *sprite, const char *filename) -{ - GError *error = NULL; - guint i, depth; - SwfdecAudio *audio; - SwfdecBufferQueue *queue; - SwfdecBuffer *buffer, *wav; - - for (i = 0; i < sprite->n_frames; i++) { - if (sprite->frames[i].sound_head) - break; - } - if (i >= sprite->n_frames) { - g_printerr ("No sound in sprite %u\n", SWFDEC_CHARACTER (sprite)->id); - return FALSE; - } - audio = swfdec_audio_stream_new (NULL, sprite, i); - i = 4096; - queue = swfdec_buffer_queue_new (); - while (i > 0) { - buffer = swfdec_buffer_new (); - buffer->data = g_malloc0 (i * 4); - buffer->length = i * 4; -#if 0 - if (i > 1234) { - swfdec_audio_render (audio, (gint16 *) buffer->data, 0, 1234); - swfdec_audio_render (audio, (gint16 *) buffer->data + 2468, 1234, i - 1234); - } else -#endif - { - swfdec_audio_render (audio, (gint16 *) (void *) buffer->data, 0, i); - } - i = swfdec_audio_iterate (audio, i); - i = MIN (i, 4096); - swfdec_buffer_queue_push (queue, buffer); - } - depth = swfdec_buffer_queue_get_depth (queue); - if (depth == 0) { - swfdec_buffer_queue_unref (queue); - g_printerr ("Sprite contains no sound\n"); - return FALSE; - } - buffer = swfdec_buffer_queue_pull (queue, depth); - swfdec_buffer_queue_unref (queue); - wav = encode_wav (buffer, swfdec_audio_format_new (44100, 2, TRUE)); - swfdec_buffer_unref (buffer); - if (!g_file_set_contents (filename, (char *) wav->data, - wav->length, &error)) { - g_printerr ("Couldn't save sound to file \"%s\": %s\n", filename, error->message); - swfdec_buffer_unref (wav); - g_error_free (error); - return FALSE; - } - swfdec_buffer_unref (wav); - return TRUE; -} - -static cairo_surface_t * -surface_create_for_filename (const char *filename, int width, int height) -{ - guint len = strlen (filename); - cairo_surface_t *surface; - if (FALSE) { -#ifdef CAIRO_HAS_PDF_SURFACE - } else if (len >= 3 && g_ascii_strcasecmp (filename + len - 3, "pdf") == 0) { - surface = cairo_pdf_surface_create (filename, width, height); -#endif -#ifdef CAIRO_HAS_SVG_SURFACE - } else if (len >= 3 && g_ascii_strcasecmp (filename + len - 3, "svg") == 0) { - surface = cairo_svg_surface_create (filename, width, height); -#endif - } else { - surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); - } - return surface; -} - -static gboolean -surface_destroy_for_type (cairo_surface_t *surface, const char *filename) -{ - if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_IMAGE) { - cairo_status_t status = cairo_surface_write_to_png (surface, filename); - if (status != CAIRO_STATUS_SUCCESS) { - g_printerr ("Error saving file: %s\n", cairo_status_to_string (status)); - cairo_surface_destroy (surface); - return FALSE; - } - } - cairo_surface_destroy (surface); - return TRUE; -} - -static gboolean -export_graphic (SwfdecGraphic *graphic, const char *filename) -{ - cairo_surface_t *surface; - cairo_t *cr; - guint width, height; - const SwfdecColorTransform trans = { 256, 0, 256, 0, 256, 0, 256, 0 }; - - if (SWFDEC_IS_SPRITE (graphic)) { - g_printerr ("Sprites can not be exported\n"); - return FALSE; - } - if (SWFDEC_IS_BUTTON (graphic)) { - g_printerr ("Buttons can not be exported\n"); - return FALSE; - } - width = ceil (graphic->extents.x1 / SWFDEC_TWIPS_SCALE_FACTOR) - - floor (graphic->extents.x0 / SWFDEC_TWIPS_SCALE_FACTOR); - height = ceil (graphic->extents.y1 / SWFDEC_TWIPS_SCALE_FACTOR) - - floor (graphic->extents.y0 / SWFDEC_TWIPS_SCALE_FACTOR); - surface = surface_create_for_filename (filename, width, height); - cr = cairo_create (surface); - cairo_translate (cr, - floor (graphic->extents.x0 / SWFDEC_TWIPS_SCALE_FACTOR), - - floor (graphic->extents.y0 / SWFDEC_TWIPS_SCALE_FACTOR)); - cairo_scale (cr, 1.0 / SWFDEC_TWIPS_SCALE_FACTOR, 1.0 / SWFDEC_TWIPS_SCALE_FACTOR); - swfdec_graphic_render (graphic, cr, &trans, &graphic->extents); - cairo_show_page (cr); - cairo_destroy (cr); - return surface_destroy_for_type (surface, filename); -} - -static gboolean -export_image (SwfdecImage *image, const char *filename) -{ - cairo_surface_t *surface = swfdec_image_create_surface (image); - - if (surface == NULL) - return FALSE; - return surface_destroy_for_type (surface, filename); -} - -static void -usage (const char *app) -{ - g_print ("usage: %s SWFFILE ID OUTFILE\n\n", app); -} - -int -main (int argc, char *argv[]) -{ - SwfdecCharacter *character; - int ret = 0; - SwfdecPlayer *player; - glong id; - - swfdec_init (); - - if (argc != 4) { - usage (argv[0]); - return 0; - } - - player = swfdec_player_new_from_file (argv[1]); - /* FIXME: HACK! */ - swfdec_player_advance (player, 0); - if (!SWFDEC_IS_SPRITE_MOVIE (player->priv->roots->data)) { - g_printerr ("Error parsing file \"%s\"\n", argv[1]); - g_object_unref (player); - player = NULL; - return 1; - } - id = strtol (argv[2], NULL, 0); - if (id >= 0) { - character = swfdec_swf_decoder_get_character ( - SWFDEC_SWF_DECODER (SWFDEC_MOVIE (player->priv->roots->data)->resource->decoder), - id); - } else { - character = SWFDEC_CHARACTER (SWFDEC_SWF_DECODER ( - SWFDEC_MOVIE (player->priv->roots->data)->resource->decoder)->main_sprite); - } - if (SWFDEC_IS_SPRITE (character)) { - if (!export_sprite_sound (SWFDEC_SPRITE (character), argv[3])) - ret = 1; - } else if (SWFDEC_IS_SOUND (character)) { - if (!export_sound (SWFDEC_SOUND (character), argv[3])) - ret = 1; - } else if (SWFDEC_IS_GRAPHIC (character)) { - if (!export_graphic (SWFDEC_GRAPHIC (character), argv[3])) - ret = 1; - } else if (SWFDEC_IS_IMAGE (character)) { - if (!export_image (SWFDEC_IMAGE (character), argv[3])) - ret = 1; - } else { - g_printerr ("id %ld does not specify an exportable object\n", id); - ret = 1; - } - - g_object_unref (player); - player = NULL; - - return ret; -} - diff --git a/test/swfdec_out.c b/test/swfdec_out.c deleted file mode 100644 index ecf5a83..0000000 --- a/test/swfdec_out.c +++ /dev/null @@ -1,383 +0,0 @@ -/* Swfdec - * Copyright (C) 2007 Benjamin Otte <otte at gnome.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <string.h> - -#include "swfdec_out.h" - -SwfdecOut * -swfdec_out_open (void) -{ - SwfdecOut *out = g_new0 (SwfdecOut, 1); - - out->data = g_malloc (SWFDEC_OUT_INITIAL); - out->ptr = out->data; - out->end = out->data + SWFDEC_OUT_INITIAL; - - return out; -} - -static void -swfdec_out_syncbits (SwfdecOut *out) -{ - g_return_if_fail (out != NULL); - - if (out->idx > 0) { - out->ptr++; - out->idx = 0; - } -} - -SwfdecBuffer * -swfdec_out_close (SwfdecOut *out) -{ - SwfdecBuffer *buffer; - - g_return_val_if_fail (out != NULL, NULL); - - swfdec_out_syncbits (out); - - buffer = swfdec_buffer_new (); - buffer->data = out->data; - buffer->length = out->ptr - out->data; - - g_free (out); - - return buffer; -} - -unsigned int -swfdec_out_get_bits (SwfdecOut *out) -{ - g_return_val_if_fail (out != NULL, 0); - - return (out->ptr - out->data) * 8 + out->idx; -} - -unsigned int -swfdec_out_left (SwfdecOut *out) -{ - g_return_val_if_fail (out != NULL, 0); - - return (out->end - out->ptr) * 8 - out->idx; -} - -void -swfdec_out_ensure_bits (SwfdecOut *out, unsigned int bits) -{ - unsigned int current, taken, needed; - - g_return_if_fail (out != NULL); - - current = swfdec_out_left (out); - if (current >= bits) - return; - taken = out->ptr - out->data; - needed = (bits - current + 7) / 8; - needed += SWFDEC_OUT_STEP; - needed -= needed % SWFDEC_OUT_STEP; - needed += out->end - out->data; - out->data = g_realloc (out->data, needed); - out->ptr = out->data + taken; - out->end = out->data + needed; -} - -void -swfdec_out_prepare_bytes (SwfdecOut *out, unsigned int bytes) -{ - g_return_if_fail (out != NULL); - - swfdec_out_syncbits (out); - swfdec_out_ensure_bits (out, bytes * 8); -} - -void -swfdec_out_put_data (SwfdecOut *out, const guint8 *data, guint length) -{ - g_return_if_fail (out != NULL); - - swfdec_out_prepare_bytes (out, length); - memcpy (out->ptr, data, length); - out->ptr += length; -} - -void -swfdec_out_put_buffer (SwfdecOut *out, SwfdecBuffer *buffer) -{ - g_return_if_fail (out != NULL); - - swfdec_out_prepare_bytes (out, buffer->length); - memcpy (out->ptr, buffer->data, buffer->length); - out->ptr += buffer->length; -} - -void -swfdec_out_put_u8 (SwfdecOut *out, guint i) -{ - g_return_if_fail (i <= G_MAXUINT8); - - swfdec_out_prepare_bytes (out, 1); - *out->ptr = i; - out->ptr++; -} - -void -swfdec_out_put_u16 (SwfdecOut *out, guint i) -{ - g_return_if_fail (i <= G_MAXUINT16); - - swfdec_out_prepare_bytes (out, 2); - *(guint16 *)out->ptr = GUINT16_TO_LE (i); - out->ptr += 2; -} - -void -swfdec_out_put_u32 (SwfdecOut *out, guint i) -{ - g_return_if_fail (i <= G_MAXUINT32); - - swfdec_out_prepare_bytes (out, 4); - *(guint32 *)out->ptr = GUINT32_TO_LE (i); - out->ptr += 4; -} - -void -swfdec_out_put_bit (SwfdecOut *out, gboolean bit) -{ - g_return_if_fail (out != NULL); - - swfdec_out_put_bits (out, bit ? 1 : 0, 1); -} - -void -swfdec_out_put_bits (SwfdecOut *out, guint bits, guint n_bits) -{ - g_return_if_fail (out != NULL); - - swfdec_out_ensure_bits (out, n_bits); - - /* FIXME: implement this less braindead */ - while (n_bits) { - guint bits_now = MIN (n_bits, 8 - out->idx); - guint value = bits >> (n_bits - bits_now); - - /* clear data if necessary */ - if (out->idx == 0) - *out->ptr = 0; - value &= (1 << bits_now) - 1; - value <<= 8 - out->idx - bits_now; - *out->ptr |= value; - out->idx += bits_now; - g_assert (out->idx <= 8); - if (out->idx == 8) { - out->ptr ++; - out->idx = 0; - } - n_bits -= bits_now; - } -} - -void -swfdec_out_put_sbits (SwfdecOut *out, int bits, guint n_bits) -{ - g_return_if_fail (out != NULL); - swfdec_out_put_bits (out, bits, n_bits); -} - -void -swfdec_out_put_string (SwfdecOut *out, const char *s) -{ - guint len; - - g_return_if_fail (out != NULL); - g_return_if_fail (s != NULL); - - len = strlen (s) + 1; - - swfdec_out_prepare_bytes (out, len); - memcpy (out->ptr, s, len); - out->ptr += len; -} - -static guint -swfdec_out_bits_required (guint x) -{ - guint ret = 0; - - while (x > 0) { - x >>= 1; - ret++; - } - return ret; -} - -static guint -swfdec_out_sbits_required (int x) -{ - if (x < 0) - x = !x; - return swfdec_out_bits_required (x) + 1; -} - -void -swfdec_out_put_rect (SwfdecOut *out, const SwfdecRect *rect) -{ - int x0, x1, y0, y1; - guint req, tmp; - - g_return_if_fail (out != NULL); - g_return_if_fail (rect != NULL); - - x0 = rect->x0; - y0 = rect->y0; - x1 = rect->x1; - y1 = rect->y1; - req = swfdec_out_sbits_required (x0); - tmp = swfdec_out_sbits_required (y0); - req = MAX (req, tmp); - tmp = swfdec_out_sbits_required (x1); - req = MAX (req, tmp); - tmp = swfdec_out_sbits_required (y1); - req = MAX (req, tmp); - swfdec_out_syncbits (out); - swfdec_out_put_bits (out, req, 5); - swfdec_out_put_sbits (out, x0, req); - swfdec_out_put_sbits (out, x1, req); - swfdec_out_put_sbits (out, y0, req); - swfdec_out_put_sbits (out, y1, req); - swfdec_out_syncbits (out); -} - -void -swfdec_out_put_matrix (SwfdecOut *out, const cairo_matrix_t *matrix) -{ - int x, y; - unsigned int xbits, ybits; - - if (matrix->xx != 1.0 || matrix->yy != 1.0) { - swfdec_out_put_bit (out, 1); - x = SWFDEC_DOUBLE_TO_FIXED (matrix->xx); - y = SWFDEC_DOUBLE_TO_FIXED (matrix->yy); - xbits = swfdec_out_sbits_required (x); - ybits = swfdec_out_sbits_required (y); - xbits = MAX (xbits, ybits); - swfdec_out_put_bits (out, xbits, 5); - swfdec_out_put_sbits (out, x, xbits); - swfdec_out_put_sbits (out, y, xbits); - } else { - swfdec_out_put_bit (out, 0); - } - if (matrix->xy != 0.0 || matrix->yx != 0.0) { - swfdec_out_put_bit (out, 1); - x = SWFDEC_DOUBLE_TO_FIXED (matrix->yx); - y = SWFDEC_DOUBLE_TO_FIXED (matrix->xy); - xbits = swfdec_out_sbits_required (x); - ybits = swfdec_out_sbits_required (y); - xbits = MAX (xbits, ybits); - swfdec_out_put_bits (out, xbits, 5); - swfdec_out_put_sbits (out, x, xbits); - swfdec_out_put_sbits (out, y, xbits); - } else { - swfdec_out_put_bit (out, 0); - } - x = matrix->x0; - y = matrix->y0; - xbits = swfdec_out_sbits_required (x); - ybits = swfdec_out_sbits_required (y); - xbits = MAX (xbits, ybits); - swfdec_out_put_bits (out, xbits, 5); - swfdec_out_put_sbits (out, x, xbits); - swfdec_out_put_sbits (out, y, xbits); - swfdec_out_syncbits (out); -} - -void -swfdec_out_put_color_transform (SwfdecOut *out, const SwfdecColorTransform *trans) -{ - gboolean has_add, has_mult; - unsigned int n_bits, tmp; - - has_mult = trans->ra != 256 || trans->ga != 256 || trans->ba != 256 || trans->aa != 256; - has_add = trans->rb != 0 || trans->gb != 0 || trans->bb != 0 || trans->ab != 0; - if (has_mult) { - n_bits = swfdec_out_sbits_required (trans->ra); - tmp = swfdec_out_sbits_required (trans->ga); - n_bits = MAX (tmp, n_bits); - tmp = swfdec_out_sbits_required (trans->ba); - n_bits = MAX (tmp, n_bits); - tmp = swfdec_out_sbits_required (trans->aa); - n_bits = MAX (tmp, n_bits); - } else { - n_bits = 0; - } - if (has_add) { - tmp = swfdec_out_sbits_required (trans->rb); - n_bits = MAX (tmp, n_bits); - tmp = swfdec_out_sbits_required (trans->gb); - n_bits = MAX (tmp, n_bits); - tmp = swfdec_out_sbits_required (trans->bb); - n_bits = MAX (tmp, n_bits); - tmp = swfdec_out_sbits_required (trans->ab); - n_bits = MAX (tmp, n_bits); - } - if (n_bits >= (1 << 4)) - n_bits = (1 << 4) - 1; - swfdec_out_put_bit (out, has_add); - swfdec_out_put_bit (out, has_mult); - swfdec_out_put_bits (out, n_bits, 4); - if (has_mult) { - swfdec_out_put_sbits (out, trans->ra, n_bits); - swfdec_out_put_sbits (out, trans->ga, n_bits); - swfdec_out_put_sbits (out, trans->ba, n_bits); - swfdec_out_put_sbits (out, trans->aa, n_bits); - } - if (has_add) { - swfdec_out_put_sbits (out, trans->rb, n_bits); - swfdec_out_put_sbits (out, trans->gb, n_bits); - swfdec_out_put_sbits (out, trans->bb, n_bits); - swfdec_out_put_sbits (out, trans->ab, n_bits); - } - swfdec_out_syncbits (out); -} - -void -swfdec_out_put_rgb (SwfdecOut *out, SwfdecColor color) -{ - g_return_if_fail (out != NULL); - - swfdec_out_put_u8 (out, SWFDEC_COLOR_R (color)); - swfdec_out_put_u8 (out, SWFDEC_COLOR_G (color)); - swfdec_out_put_u8 (out, SWFDEC_COLOR_B (color)); -} - -void -swfdec_out_put_rgba (SwfdecOut *out, SwfdecColor color) -{ - g_return_if_fail (out != NULL); - - swfdec_out_put_u8 (out, SWFDEC_COLOR_R (color)); - swfdec_out_put_u8 (out, SWFDEC_COLOR_G (color)); - swfdec_out_put_u8 (out, SWFDEC_COLOR_B (color)); - swfdec_out_put_u8 (out, SWFDEC_COLOR_A (color)); -} - diff --git a/test/swfdec_out.h b/test/swfdec_out.h deleted file mode 100644 index e343f9d..0000000 --- a/test/swfdec_out.h +++ /dev/null @@ -1,88 +0,0 @@ -/* 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_OUT_H__ -#define __SWFDEC_OUT_H__ - -#include <libswfdec/swfdec_buffer.h> -#include <libswfdec/swfdec_color.h> -#include <libswfdec/swfdec_rect.h> - -G_BEGIN_DECLS - - -typedef struct _SwfdecOut SwfdecOut; - -struct _SwfdecOut { - unsigned char * data; - unsigned char * ptr; - unsigned int idx; - unsigned char * end; -}; - -#define SWFDEC_OUT_INITIAL (32) -#define SWFDEC_OUT_STEP (32) - -SwfdecOut * swfdec_out_open (void); -SwfdecBuffer * swfdec_out_close (SwfdecOut * out); - -unsigned int swfdec_out_get_bits (SwfdecOut * out); -unsigned int swfdec_out_left (SwfdecOut * out); -void swfdec_out_ensure_bits (SwfdecOut * out, - unsigned int bits); -void swfdec_out_prepare_bytes (SwfdecOut * out, - unsigned int bytes); - -void swfdec_out_put_bit (SwfdecOut * out, - gboolean bit); -void swfdec_out_put_bits (SwfdecOut * out, - guint bits, - guint n_bits); -void swfdec_out_put_sbits (SwfdecOut * out, - int bits, - guint n_bits); -void swfdec_out_put_data (SwfdecOut * out, - const guint8 * data, - guint length); -void swfdec_out_put_buffer (SwfdecOut * out, - SwfdecBuffer * buffer); -void swfdec_out_put_u8 (SwfdecOut * out, - guint i); -void swfdec_out_put_u16 (SwfdecOut * out, - guint i); -void swfdec_out_put_u32 (SwfdecOut * out, - guint i); -void swfdec_out_put_string (SwfdecOut * out, - const char * s); - -void swfdec_out_put_rgb (SwfdecOut * out, - SwfdecColor color); -void swfdec_out_put_rgba (SwfdecOut * out, - SwfdecColor color); -void swfdec_out_put_rect (SwfdecOut * out, - const SwfdecRect * rect); -void swfdec_out_put_matrix (SwfdecOut * out, - const cairo_matrix_t * matrix); -void swfdec_out_put_color_transform (SwfdecOut * out, - const SwfdecColorTransform *trans); - - -G_END_DECLS - -#endif diff --git a/test/swfedit.c b/test/swfedit.c deleted file mode 100644 index 24f2980..0000000 --- a/test/swfedit.c +++ /dev/null @@ -1,138 +0,0 @@ -/* Swfedit - * 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 <gtk/gtk.h> -#include "swfedit_file.h" - -static void -save (GtkButton *button, SwfeditFile *file) -{ - GtkWidget *dialog; - GError *error = NULL; - - dialog = gtk_file_chooser_dialog_new ("Save file...", - GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (button))), - GTK_FILE_CHOOSER_ACTION_SAVE, - GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, - GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, - NULL); - gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT); - gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE); - gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (dialog), file->filename); - if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { - g_free (file->filename); - file->filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); - if (!swfedit_file_save (file, &error)) { - g_printerr ("Error saving file: %s\n", error->message); - g_error_free (error); - } - } - gtk_widget_destroy (dialog); -} - -static void -cell_renderer_edited (GtkCellRenderer *renderer, char *path, - char *new_text, SwfeditFile *file) -{ - GtkTreeIter iter; - - if (!gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (file), - &iter, path)) { - g_assert_not_reached (); - } - swfedit_token_set_iter (SWFEDIT_TOKEN (file), &iter, new_text); -} - -static gboolean -open_window (char *filename) -{ - SwfeditFile *file; - GtkWidget *window, *scroll, *box, *button, *treeview; - GError *error = NULL; - GtkTreeViewColumn *column; - GtkCellRenderer *renderer; - char *basename; - - file = swfedit_file_new (filename, &error); - if (file == NULL) { - g_printerr ("Error opening file %s: %s\n", filename, error->message); - g_error_free (error); - return FALSE; - } - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - basename = g_path_get_basename (filename); - if (basename) { - gtk_window_set_title (GTK_WINDOW (window), basename); - g_free (basename); - } - g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); - - box = gtk_vbox_new (FALSE, 3); - gtk_container_add (GTK_CONTAINER (window), box); - - scroll = gtk_scrolled_window_new (NULL, NULL); - gtk_box_pack_start (GTK_BOX (box), scroll, TRUE, TRUE, 0); - - treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (file)); - gtk_container_add (GTK_CONTAINER (scroll), treeview); - - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("Name", renderer, - "text", SWFEDIT_COLUMN_NAME, "sensitive", SWFEDIT_COLUMN_VALUE_EDITABLE, NULL); - gtk_tree_view_column_set_resizable (column, TRUE); - gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); - - renderer = gtk_cell_renderer_text_new (); - g_object_set (G_OBJECT (renderer), "editable", TRUE, NULL); - g_signal_connect (renderer, "edited", G_CALLBACK (cell_renderer_edited), file); - column = gtk_tree_view_column_new_with_attributes ("Value", renderer, - "text", SWFEDIT_COLUMN_VALUE, "visible", SWFEDIT_COLUMN_VALUE_VISIBLE, - "sensitive", SWFEDIT_COLUMN_VALUE_EDITABLE, NULL); - gtk_tree_view_column_set_resizable (column, TRUE); - gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); - - button = gtk_button_new_from_stock (GTK_STOCK_SAVE); - g_signal_connect (button, "clicked", G_CALLBACK (save), file); - gtk_box_pack_start (GTK_BOX (box), button, FALSE, TRUE, 0); - - gtk_widget_show_all (window); - return TRUE; -} - -int -main (int argc, char **argv) -{ - gtk_init (&argc, &argv); - - if (argc <= 1) { - g_print ("Usage: %s FILENAME\n", argv[0]); - return 1; - } - if (open_window (argv[1])) { - gtk_main (); - return 0; - } else { - return 1; - } -} - diff --git a/test/swfedit_file.c b/test/swfedit_file.c deleted file mode 100644 index e257010..0000000 --- a/test/swfedit_file.c +++ /dev/null @@ -1,297 +0,0 @@ -/* Swfedit - * 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 <zlib.h> - -#include "libswfdec/swfdec_bits.h" -#include "libswfdec/swfdec_buffer.h" -#include "libswfdec/swfdec_debug.h" -#include "libswfdec/swfdec_swf_decoder.h" -#include "swfdec_out.h" -#include "swfedit_file.h" -#include "swfedit_tag.h" - -G_DEFINE_TYPE (SwfeditFile, swfedit_file, SWFEDIT_TYPE_TOKEN) - -static void -swfedit_file_dispose (GObject *object) -{ - SwfeditFile *file = SWFEDIT_FILE (object); - - g_free (file->filename); - - G_OBJECT_CLASS (swfedit_file_parent_class)->dispose (object); -} - -static void * -zalloc (void *opaque, unsigned int items, unsigned int size) -{ - return g_malloc (items * size); -} - -static void -zfree (void *opaque, void *addr) -{ - g_free (addr); -} - -static SwfdecBuffer * -swfenc_file_inflate (SwfdecBits *bits, guint size) -{ - SwfdecBuffer *decoded, *encoded; - z_stream z; - int ret; - - encoded = swfdec_bits_get_buffer (bits, -1); - if (encoded == NULL) - return NULL; - decoded = swfdec_buffer_new_and_alloc (size); - z.zalloc = zalloc; - z.zfree = zfree; - z.opaque = NULL; - z.next_in = encoded->data; - z.avail_in = encoded->length; - z.next_out = decoded->data; - z.avail_out = decoded->length; - ret = inflateInit (&z); - SWFDEC_DEBUG ("inflateInit returned %d", ret); - if (ret >= Z_OK) { - ret = inflate (&z, Z_SYNC_FLUSH); - SWFDEC_DEBUG ("inflate returned %d", ret); - } - inflateEnd (&z); - swfdec_buffer_unref (encoded); - if (ret < Z_OK) { - swfdec_buffer_unref (decoded); - return NULL; - } - return decoded; -} - -static SwfdecBuffer * -swf_parse_header1 (SwfeditFile *file, SwfdecBits *bits, GError **error) -{ - guint sig1, sig2, sig3, bytes_total; - - sig1 = swfdec_bits_get_u8 (bits); - sig2 = swfdec_bits_get_u8 (bits); - sig3 = swfdec_bits_get_u8 (bits); - if ((sig1 != 'F' && sig1 != 'C') || sig2 != 'W' || sig3 != 'S') { - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, - "This is not a SWF file"); - return NULL; - } - - swfedit_token_add (SWFEDIT_TOKEN (file), "version", SWFEDIT_TOKEN_UINT8, - GUINT_TO_POINTER (swfdec_bits_get_u8 (bits))); - bytes_total = swfdec_bits_get_u32 (bits) - 8; - - if (sig1 == 'C') { - /* compressed */ - SwfdecBuffer *ret = swfenc_file_inflate (bits, bytes_total); - if (ret == NULL) - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, - "Unable to uncompress file"); - return ret; - } else { - SwfdecBuffer *ret = swfdec_bits_get_buffer (bits, bytes_total); - if (ret == NULL) - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, - "File too small"); - return ret; - } -} - -static void -swf_parse_header2 (SwfeditFile *file, SwfdecBits *bits) -{ - swfedit_tag_read_token (SWFEDIT_TOKEN (file), bits, "rect", SWFEDIT_TOKEN_RECT, NULL); - swfedit_tag_read_token (SWFEDIT_TOKEN (file), bits, "rate", SWFEDIT_TOKEN_UINT16, NULL); - swfedit_tag_read_token (SWFEDIT_TOKEN (file), bits, "frames", SWFEDIT_TOKEN_UINT16, NULL); -} - -static gboolean -swfedit_file_parse (SwfeditFile *file, SwfdecBits *bits, GError **error) -{ - SwfdecBuffer *next; - - next = swf_parse_header1 (file, bits, error); - if (next == NULL) - return FALSE; - swfdec_bits_init (bits, next); - swf_parse_header2 (file, bits); - - while (swfdec_bits_left (bits)) { - guint x = swfdec_bits_get_u16 (bits); - G_GNUC_UNUSED guint tag = (x >> 6) & 0x3ff; - guint tag_len = x & 0x3f; - SwfdecBuffer *buffer; - SwfeditTag *item; - - if (tag_len == 0x3f) - tag_len = swfdec_bits_get_u32 (bits); - if (tag == 0) - break; - if (tag_len > 0) - buffer = swfdec_bits_get_buffer (bits, tag_len); - else - buffer = swfdec_buffer_new (); - if (buffer == NULL) { - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, - "Invalid contents in file"); - return FALSE; - } - item = swfedit_tag_new (SWFEDIT_TOKEN (file), tag, buffer); - swfedit_token_add (SWFEDIT_TOKEN (file), - swfdec_swf_decoder_get_tag_name (tag), - SWFEDIT_TOKEN_OBJECT, item); - } - swfdec_buffer_unref (next); - return TRUE; -} - -static void -swfedit_file_class_init (SwfeditFileClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = swfedit_file_dispose; -} - -static void -swfedit_file_init (SwfeditFile *s) -{ -} - -SwfeditFile * -swfedit_file_new (const char *filename, GError **error) -{ - SwfeditFile *file; - SwfdecBuffer *buffer; - SwfdecBits bits; - char *absolute; - - if (g_path_is_absolute (filename)) { - absolute = g_strdup (filename); - } else { - char *dir = g_get_current_dir (); - absolute = g_build_filename (dir, filename, NULL); - g_free (dir); - } - buffer = swfdec_buffer_new_from_file (filename, error); - if (buffer == NULL) - return NULL; - swfdec_bits_init (&bits, buffer); - file = g_object_new (SWFEDIT_TYPE_FILE, NULL); - file->filename = absolute; - if (!swfedit_file_parse (file, &bits, error)) { - swfdec_buffer_unref (buffer); - g_object_unref (file); - return NULL; - } - swfdec_buffer_unref (buffer); - return file; -} - -static SwfdecBuffer * -swfedit_file_write (SwfeditFile *file) -{ - guint i; - SwfeditToken *token = SWFEDIT_TOKEN (file); - SwfdecBufferQueue *queue; - SwfdecBuffer *buffer; - SwfdecOut *out; - - queue = swfdec_buffer_queue_new (); - /* write second part of header */ - out = swfdec_out_open (); - swfedit_tag_write_token (token, out, 1); - swfedit_tag_write_token (token, out, 2); - swfedit_tag_write_token (token, out, 3); - swfdec_buffer_queue_push (queue, swfdec_out_close (out)); - - for (i = 4; i < token->tokens->len; i++) { - SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, i); - g_assert (entry->type == SWFEDIT_TOKEN_OBJECT); - - buffer = swfedit_tag_write (entry->value); - out = swfdec_out_open (); - swfdec_out_put_u16 (out, SWFEDIT_TAG (entry->value)->tag << 6 | - MIN (buffer->length, 0x3f)); - if (buffer->length >= 0x3f) { - swfdec_out_put_u32 (out, buffer->length); - } - swfdec_buffer_queue_push (queue, swfdec_out_close (out)); - swfdec_buffer_queue_push (queue, buffer); - } - /* write closing tag */ - buffer = swfdec_buffer_new_and_alloc0 (2); - swfdec_buffer_queue_push (queue, buffer); - - /* FIXME: implement compression */ - out = swfdec_out_open (); - swfdec_out_put_u8 (out, 'F'); - swfdec_out_put_u8 (out, 'W'); - swfdec_out_put_u8 (out, 'S'); - swfedit_tag_write_token (token, out, 0); - swfdec_out_put_u32 (out, swfdec_buffer_queue_get_depth (queue) + 8); - swfdec_out_prepare_bytes (out, swfdec_buffer_queue_get_depth (queue)); - while ((buffer = swfdec_buffer_queue_pull_buffer (queue))) { - swfdec_out_put_buffer (out, buffer); - swfdec_buffer_unref (buffer); - } - swfdec_buffer_queue_unref (queue); - return swfdec_out_close (out); -} - -gboolean -swfedit_file_save (SwfeditFile *file, GError **error) -{ - SwfdecBuffer *buffer; - gboolean ret; - - g_return_val_if_fail (SWFEDIT_IS_FILE (file), FALSE); - - buffer = swfedit_file_write (file); - if (buffer == NULL) { - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, - "Failed to render file"); - return FALSE; - } - ret = g_file_set_contents (file->filename, (char *) buffer->data, - buffer->length, error); - swfdec_buffer_unref (buffer); - return ret; -} - -guint -swfedit_file_get_version (SwfeditFile *file) -{ - SwfeditTokenEntry *entry; - - g_return_val_if_fail (SWFEDIT_FILE (file), 3); - - entry = &g_array_index (SWFEDIT_TOKEN (file)->tokens, SwfeditTokenEntry, 0); - return GPOINTER_TO_UINT (entry->value); -} - diff --git a/test/swfedit_file.h b/test/swfedit_file.h deleted file mode 100644 index ecd096a..0000000 --- a/test/swfedit_file.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Swfedit - * 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 __SWFEDIT_FILE_H__ -#define __SWFEDIT_FILE_H__ - -#include <libswfdec/swfdec_rect.h> -#include "swfedit_token.h" - -G_BEGIN_DECLS - -typedef struct _SwfeditFile SwfeditFile; -typedef struct _SwfeditFileClass SwfeditFileClass; - -#define SWFEDIT_TYPE_FILE (swfedit_file_get_type()) -#define SWFEDIT_IS_FILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFEDIT_TYPE_FILE)) -#define SWFEDIT_IS_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFEDIT_TYPE_FILE)) -#define SWFEDIT_FILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFEDIT_TYPE_FILE, SwfeditFile)) -#define SWFEDIT_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFEDIT_TYPE_FILE, SwfeditFileClass)) -#define SWFEDIT_FILE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFEDIT_TYPE_FILE, SwfeditFileClass)) - -struct _SwfeditFile { - SwfeditToken token; - - char * filename; /* name this file is saved to */ -}; - -struct _SwfeditFileClass { - SwfeditTokenClass token_class; -}; - -GType swfedit_file_get_type (void); - -SwfeditFile * swfedit_file_new (const char * filename, - GError ** error); - -gboolean swfedit_file_save (SwfeditFile * file, - GError ** error); -guint swfedit_file_get_version (SwfeditFile * file); - - -G_END_DECLS - -#endif diff --git a/test/swfedit_list.c b/test/swfedit_list.c deleted file mode 100644 index 45e0dd5..0000000 --- a/test/swfedit_list.c +++ /dev/null @@ -1,149 +0,0 @@ -/* Swfedit - * 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 "swfedit_list.h" - -G_DEFINE_TYPE (SwfeditList, swfedit_list, SWFEDIT_TYPE_TOKEN) - -static void -swfedit_list_dispose (GObject *object) -{ - //SwfeditList *list = SWFEDIT_LIST (object); - - G_OBJECT_CLASS (swfedit_list_parent_class)->dispose (object); -} - -static void -swfedit_list_changed (SwfeditToken *token, guint i) -{ - guint j; - SwfeditList *list = SWFEDIT_LIST (token); - SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, i); - - /* update visibility */ - for (j = i + 1; j % list->n_defs != 0; j++) { - if (list->def[j].n_items == (j % list->n_defs) + 1) { - swfedit_token_set_visible (token, j, entry->value != NULL); - } - } - /* update length */ - j = list->def[i % list->n_defs].n_items; - if (j != 0) { - entry = &g_array_index (token->tokens, - SwfeditTokenEntry, j - 1); - if (entry->type == SWFEDIT_TOKEN_UINT32) { - SwfdecOut *out = swfdec_out_open (); - SwfdecBuffer *buffer; - swfedit_tag_write_token (token, out, i); - buffer = swfdec_out_close (out); - if (entry->value != GUINT_TO_POINTER (buffer->length)) { - swfedit_token_set (token, i / list->n_defs * list->n_defs + j - 1, - GUINT_TO_POINTER (buffer->length)); - } - swfdec_buffer_unref (buffer); - } - } - /* maybe add items */ - if (i == token->tokens->len - 1) { - for (j = 0; j < list->n_defs; j++) { - const SwfeditTagDefinition *def = &list->def[(j + 1) % list->n_defs]; - swfedit_tag_add_token (SWFEDIT_TOKEN (list), def->name, def->type, def->hint); - } - } -} - -static void -swfedit_list_class_init (SwfeditListClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - SwfeditTokenClass *token_class = SWFEDIT_TOKEN_CLASS (klass); - - object_class->dispose = swfedit_list_dispose; - - token_class->changed = swfedit_list_changed; -} - -static void -swfedit_list_init (SwfeditList *list) -{ -} - -static SwfeditList * -swfedit_list_new_internal (const SwfeditTagDefinition *def) -{ - SwfeditList *list; - - list = g_object_new (SWFEDIT_TYPE_LIST, NULL); - list->def = def; - for (; def->name; def++) - list->n_defs++; - - return list; -} - -SwfeditList * -swfedit_list_new (const SwfeditTagDefinition *def) -{ - SwfeditList *list; - - g_return_val_if_fail (def != NULL, NULL); - - list = swfedit_list_new_internal (def); - swfedit_tag_add_token (SWFEDIT_TOKEN (list), def->name, def->type, def->hint); - - return list; -} - -SwfeditList * -swfedit_list_new_read (SwfeditToken *parent, SwfdecBits *bits, const SwfeditTagDefinition *def) -{ - SwfeditList *list; - SwfeditTokenEntry *entry; - guint offset; - - g_return_val_if_fail (bits != NULL, NULL); - g_return_val_if_fail (def != NULL, NULL); - - list = swfedit_list_new_internal (def); - SWFEDIT_TOKEN (list)->parent = parent; - offset = 0; - while (TRUE) { - def = list->def; - swfedit_tag_read_tag (SWFEDIT_TOKEN (list), bits, def); - entry = &g_array_index (SWFEDIT_TOKEN (list)->tokens, SwfeditTokenEntry, - SWFEDIT_TOKEN (list)->tokens->len - 1); - if (GPOINTER_TO_UINT (entry->value) == 0) - break; - - def++; - for (;def->name != NULL; def++) { - SwfeditTagDefinition def2 = *def; - if (def2.n_items) - def2.n_items += offset; - swfedit_tag_read_tag (SWFEDIT_TOKEN (list), bits, &def2); - } - offset += list->n_defs; - } - return list; -} - diff --git a/test/swfedit_list.h b/test/swfedit_list.h deleted file mode 100644 index e0666f7..0000000 --- a/test/swfedit_list.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Swfedit - * 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 __SWFEDIT_LIST_H__ -#define __SWFEDIT_LIST_H__ - -#include "swfdec_out.h" -#include "swfedit_tag.h" - -G_BEGIN_DECLS - -typedef struct _SwfeditList SwfeditList; -typedef struct _SwfeditListClass SwfeditListClass; - -#define SWFEDIT_TYPE_LIST (swfedit_list_get_type()) -#define SWFEDIT_IS_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFEDIT_TYPE_LIST)) -#define SWFEDIT_IS_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFEDIT_TYPE_LIST)) -#define SWFEDIT_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFEDIT_TYPE_LIST, SwfeditList)) -#define SWFEDIT_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFEDIT_TYPE_LIST, SwfeditListClass)) -#define SWFEDIT_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFEDIT_TYPE_LIST, SwfeditListClass)) - -struct _SwfeditList { - SwfeditToken token; - - const SwfeditTagDefinition * def; /* definition of our items */ - guint n_defs; /* number of items in def */ -}; - -struct _SwfeditListClass { - SwfeditTokenClass token_class; -}; - -GType swfedit_list_get_type (void); - -SwfeditList * swfedit_list_new (const SwfeditTagDefinition * def); -SwfeditList * swfedit_list_new_read (SwfeditToken * parent, - SwfdecBits * bits, - const SwfeditTagDefinition * def); - -SwfdecBuffer * swfedit_list_write (SwfeditList * list); - - -G_END_DECLS - -#endif diff --git a/test/swfedit_tag.c b/test/swfedit_tag.c deleted file mode 100644 index 4a4bf67..0000000 --- a/test/swfedit_tag.c +++ /dev/null @@ -1,507 +0,0 @@ -/* Swfedit - * 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 <stdlib.h> -#include <gtk/gtk.h> - -#include <libswfdec/swfdec_bits.h> -#include <libswfdec/swfdec_debug.h> -#include <libswfdec/swfdec_script_internal.h> -#include <libswfdec/swfdec_tag.h> -#include "swfedit_tag.h" -#include "swfdec_out.h" -#include "swfedit_file.h" -#include "swfedit_list.h" - -/*** LOAD/SAVE ***/ - -static void -swfedit_object_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) -{ - SwfdecBuffer *buffer; - - g_assert (SWFEDIT_IS_TOKEN (data)); - buffer = swfedit_tag_write (data); - swfdec_out_put_buffer (out, buffer); - swfdec_buffer_unref (buffer); -} - -static gpointer -swfedit_object_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) -{ - return swfedit_list_new_read (token, bits, hint); -} - -static void -swfedit_binary_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) -{ - swfdec_out_put_buffer (out, data); -} - -static gpointer -swfedit_binary_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) -{ - SwfdecBuffer *buffer = swfdec_bits_get_buffer (bits, -1); - if (buffer == NULL) - buffer = swfdec_buffer_new (); - return buffer; -} - -static void -swfedit_bit_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) -{ - swfdec_out_put_bit (out, data ? TRUE : FALSE); -} - -static gpointer -swfedit_bit_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) -{ - return GUINT_TO_POINTER (swfdec_bits_getbit (bits) ? 1 : 0); -} - -static void -swfedit_u8_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) -{ - swfdec_out_put_u8 (out, GPOINTER_TO_UINT (data)); -} - -static gpointer -swfedit_u8_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) -{ - return GUINT_TO_POINTER ((gulong) swfdec_bits_get_u8 (bits)); -} - -static void -swfedit_u16_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) -{ - swfdec_out_put_u16 (out, GPOINTER_TO_UINT (data)); -} - -static gpointer -swfedit_u16_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) -{ - return GUINT_TO_POINTER (swfdec_bits_get_u16 (bits)); -} - -static void -swfedit_u32_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) -{ - swfdec_out_put_u32 (out, GPOINTER_TO_UINT (data)); -} - -static gpointer -swfedit_u32_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) -{ - return GUINT_TO_POINTER (swfdec_bits_get_u32 (bits)); -} - -static void -swfedit_rect_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) -{ - swfdec_out_put_rect (out, data); -} - -static gpointer -swfedit_rect_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) -{ - SwfdecRect *rect = g_new (SwfdecRect, 1); - swfdec_bits_get_rect (bits, rect); - swfdec_bits_syncbits (bits); - return rect; -} - -static void -swfedit_string_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) -{ - swfdec_out_put_string (out, data); -} - -static gpointer -swfedit_string_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) -{ - char *s; - s = swfdec_bits_get_string (bits, 7); - if (s == NULL) - s = g_strdup (""); - return s; -} - -static void -swfedit_rgb_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) -{ - swfdec_out_put_rgb (out, GPOINTER_TO_UINT (data)); -} - -static gpointer -swfedit_rgb_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) -{ - return GUINT_TO_POINTER (swfdec_bits_get_color (bits)); -} - -static void -swfedit_rgba_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) -{ - swfdec_out_put_rgba (out, GPOINTER_TO_UINT (data)); -} - -static gpointer -swfedit_rgba_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) -{ - return GUINT_TO_POINTER (swfdec_bits_get_rgba (bits)); -} - -static void -swfedit_matrix_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) -{ - swfdec_out_put_matrix (out, data); -} - -static gpointer -swfedit_matrix_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) -{ - cairo_matrix_t *matrix = g_new (cairo_matrix_t, 1); - - swfdec_bits_get_matrix (bits, matrix, NULL); - swfdec_bits_syncbits (bits); - return matrix; -} - -static void -swfedit_ctrans_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) -{ - swfdec_out_put_color_transform (out, data); -} - -static gpointer -swfedit_ctrans_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) -{ - SwfdecColorTransform *ctrans = g_new (SwfdecColorTransform, 1); - - swfdec_bits_get_color_transform (bits, ctrans); - swfdec_bits_syncbits (bits); - return ctrans; -} - -static void -swfedit_script_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) -{ - SwfdecScript *script = data; - - swfdec_out_put_buffer (out, script->buffer); -} - -static gpointer -swfedit_script_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) -{ - while (token->parent) - token = token->parent; - if (!SWFEDIT_IS_FILE (token)) - return NULL; - return swfdec_script_new_from_bits (bits, "original script", swfedit_file_get_version (SWFEDIT_FILE (token))); -} - -static void -swfedit_clipeventflags_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) -{ - while (token->parent) - token = token->parent; - g_assert (SWFEDIT_IS_FILE (token)); - if (swfedit_file_get_version (SWFEDIT_FILE (token)) >= 6) - swfdec_out_put_u32 (out, GPOINTER_TO_UINT (data)); - else - swfdec_out_put_u16 (out, GPOINTER_TO_UINT (data)); -} - -static gpointer -swfedit_clipeventflags_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) -{ - while (token->parent) - token = token->parent; - g_assert (SWFEDIT_IS_FILE (token)); - if (swfedit_file_get_version (SWFEDIT_FILE (token)) >= 6) - return GUINT_TO_POINTER (swfdec_bits_get_u32 (bits)); - else - return GUINT_TO_POINTER (swfdec_bits_get_u16 (bits)); -} - -struct { - void (* write) (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint); - gpointer (* read) (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint); -} operations[SWFEDIT_N_TOKENS] = { - { swfedit_object_write, swfedit_object_read }, - { swfedit_binary_write, swfedit_binary_read }, - { swfedit_bit_write, swfedit_bit_read }, - { swfedit_u8_write, swfedit_u8_read }, - { swfedit_u16_write, swfedit_u16_read }, - { swfedit_u32_write, swfedit_u32_read }, - { swfedit_string_write, swfedit_string_read }, - { swfedit_rect_write, swfedit_rect_read }, - { swfedit_rgb_write, swfedit_rgb_read }, - { swfedit_rgba_write, swfedit_rgba_read }, - { swfedit_matrix_write, swfedit_matrix_read }, - { swfedit_ctrans_write, swfedit_ctrans_read }, - { swfedit_script_write, swfedit_script_read }, - { swfedit_clipeventflags_write, swfedit_clipeventflags_read }, -}; - -void -swfedit_tag_write_token (SwfeditToken *token, SwfdecOut *out, guint i) -{ - SwfeditTokenEntry *entry; - - g_return_if_fail (SWFEDIT_IS_TOKEN (token)); - g_return_if_fail (i < token->tokens->len); - - entry = &g_array_index (token->tokens, - SwfeditTokenEntry, i); - g_assert (operations[entry->type].write != NULL); - operations[entry->type].write (token, entry->value, out, NULL); -} - -SwfdecBuffer * -swfedit_tag_write (SwfeditToken *token) -{ - guint i; - SwfdecOut *out; - - g_return_val_if_fail (SWFEDIT_IS_TOKEN (token), NULL); - - out = swfdec_out_open (); - for (i = 0; i < token->tokens->len; i++) { - SwfeditTokenEntry *entry = &g_array_index (token->tokens, - SwfeditTokenEntry, i); - if (entry->visible) - swfedit_tag_write_token (token, out, i); - } - return swfdec_out_close (out); -} - -void -swfedit_tag_read_token (SwfeditToken *token, SwfdecBits *bits, - const char *name, SwfeditTokenType type, gconstpointer hint) -{ - gpointer data; - - g_return_if_fail (SWFEDIT_IS_TOKEN (token)); - g_return_if_fail (name != NULL); - - g_assert (operations[type].read != NULL); - data = operations[type].read (token, bits, hint); - swfedit_token_add (token, name, type, data); -} - -/*** TAGS ***/ - -static const SwfeditTagDefinition ShowFrame[] = { { NULL, 0, 0, NULL } }; -static const SwfeditTagDefinition SetBackgroundColor[] = { { "color", SWFEDIT_TOKEN_RGB, 0, NULL }, { NULL, 0, 0, NULL } }; -static const SwfeditTagDefinition PlaceObject2Action[] = { - { "flags", SWFEDIT_TOKEN_CLIPEVENTFLAGS, 0, NULL }, - { "size", SWFEDIT_TOKEN_UINT32, 0, NULL }, - //{ "key code", SWFEDIT_TOKEN_UINT8, 0, NULL }, /* only if flag foo is set */ - { "script", SWFEDIT_TOKEN_SCRIPT, 2, NULL }, - { NULL, 0, 0, NULL } -}; -static const SwfeditTagDefinition PlaceObject2[] = { - { "has clip actions", SWFEDIT_TOKEN_BIT, 0, NULL }, - { "has clip depth", SWFEDIT_TOKEN_BIT, 0, NULL }, - { "has name", SWFEDIT_TOKEN_BIT, 0, NULL }, - { "has ratio", SWFEDIT_TOKEN_BIT, 0, NULL }, - { "has color transform", SWFEDIT_TOKEN_BIT, 0, NULL }, - { "has matrix", SWFEDIT_TOKEN_BIT, 0, NULL }, - { "has character", SWFEDIT_TOKEN_BIT, 0, NULL }, - { "move", SWFEDIT_TOKEN_BIT, 0, NULL }, - { "depth", SWFEDIT_TOKEN_UINT16, 0, NULL }, - { "character", SWFEDIT_TOKEN_UINT16, 7, NULL }, - { "matrix", SWFEDIT_TOKEN_MATRIX, 6, NULL }, - { "color transform", SWFEDIT_TOKEN_CTRANS, 5, NULL }, - { "ratio", SWFEDIT_TOKEN_UINT16, 4, NULL }, - { "name", SWFEDIT_TOKEN_STRING, 3, NULL }, - { "clip depth", SWFEDIT_TOKEN_UINT16, 2, NULL }, - { "reserved", SWFEDIT_TOKEN_UINT16, 1, NULL }, - { "all flags", SWFEDIT_TOKEN_CLIPEVENTFLAGS, 1, NULL }, - { "actions", SWFEDIT_TOKEN_OBJECT, 1, PlaceObject2Action }, - { NULL, 0, 0, NULL } -}; -static const SwfeditTagDefinition DoAction[] = { - { "action", SWFEDIT_TOKEN_SCRIPT, 0, NULL }, - { NULL, 0, 0, NULL } -}; -static const SwfeditTagDefinition DoInitAction[] = { - { "character", SWFEDIT_TOKEN_UINT16, 0, NULL }, - { "action", SWFEDIT_TOKEN_SCRIPT, 0, NULL }, - { NULL, 0, 0, NULL } -}; - -static const SwfeditTagDefinition *tags[] = { - [SWFDEC_TAG_SHOWFRAME] = ShowFrame, - [SWFDEC_TAG_SETBACKGROUNDCOLOR] = SetBackgroundColor, - [SWFDEC_TAG_PLACEOBJECT2] = PlaceObject2, - [SWFDEC_TAG_DOACTION] = DoAction, - [SWFDEC_TAG_DOINITACTION] = DoInitAction, -}; - -static const SwfeditTagDefinition * -swfedit_tag_get_definition (guint tag) -{ - if (tag >= G_N_ELEMENTS (tags)) - return NULL; - return tags[tag]; -} - -/*** SWFEDIT_TAG ***/ - -G_DEFINE_TYPE (SwfeditTag, swfedit_tag, SWFEDIT_TYPE_TOKEN) - -static void -swfedit_tag_dispose (GObject *object) -{ - //SwfeditTag *tag = SWFEDIT_TAG (object); - - G_OBJECT_CLASS (swfedit_tag_parent_class)->dispose (object); -} - -static void -swfedit_tag_changed (SwfeditToken *token, guint i) -{ - guint j; - SwfeditTag *tag = SWFEDIT_TAG (token); - SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, i); - const SwfeditTagDefinition *def = swfedit_tag_get_definition (tag->tag); - - if (def == NULL) - return; - - for (j = i + 1; def[j].name; j++) { - if (def[j].n_items == i + 1) { - swfedit_token_set_visible (token, j, entry->value != NULL); - } - } - if (def[i].n_items != 0) { - entry = &g_array_index (token->tokens, - SwfeditTokenEntry, def[i].n_items - 1); - if (entry->type == SWFEDIT_TOKEN_UINT32) { - SwfdecOut *out = swfdec_out_open (); - SwfdecBuffer *buffer; - swfedit_tag_write_token (token, out, def[i].n_items - 1); - buffer = swfdec_out_close (out); - if (entry->value != GUINT_TO_POINTER (buffer->length)) { - swfedit_token_set (token, def[i].n_items - 1, - GUINT_TO_POINTER (buffer->length)); - } - swfdec_buffer_unref (buffer); - } - } -} - -static void -swfedit_tag_class_init (SwfeditTagClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - SwfeditTokenClass *token_class = SWFEDIT_TOKEN_CLASS (klass); - - object_class->dispose = swfedit_tag_dispose; - - token_class->changed = swfedit_tag_changed; -} - -static void -swfedit_tag_init (SwfeditTag *tag) -{ -} - -void -swfedit_tag_add_token (SwfeditToken *token, const char *name, SwfeditTokenType type, - gconstpointer hint) -{ - gpointer data; - - if (type == SWFEDIT_TOKEN_OBJECT) { - data = swfedit_list_new (hint); - SWFEDIT_TOKEN (data)->parent = token; - } else { - data = swfedit_token_new_token (type); - } - swfedit_token_add (token, name, type, data); -} - -void -swfedit_tag_read_tag (SwfeditToken *token, SwfdecBits *bits, - const SwfeditTagDefinition *def) -{ - g_return_if_fail (SWFEDIT_IS_TOKEN (token)); - g_return_if_fail (bits != NULL); - g_return_if_fail (def != NULL); - - if (def->n_items != 0) { - SwfeditTokenEntry *entry = &g_array_index (token->tokens, - SwfeditTokenEntry, def->n_items - 1); - if (GPOINTER_TO_UINT (entry->value) == 0) { - swfedit_tag_add_token (token, def->name, def->type, def->hint); - swfedit_token_set_visible (token, token->tokens->len - 1, FALSE); - } else if (entry->type == SWFEDIT_TOKEN_BIT) { - swfedit_tag_read_token (token, bits, def->name, def->type, def->hint); - } else { - guint length = GPOINTER_TO_UINT (entry->value); - SwfdecBuffer *buffer = swfdec_bits_get_buffer (bits, length); - if (buffer == NULL) { - swfedit_tag_add_token (token, def->name, def->type, def->hint); - } else { - SwfdecBits bits2; - swfdec_bits_init (&bits2, buffer); - swfedit_tag_read_token (token, &bits2, def->name, def->type, def->hint); - swfdec_buffer_unref (buffer); - } - } - } else { - swfedit_tag_read_token (token, bits, def->name, def->type, def->hint); - } -} - -SwfeditTag * -swfedit_tag_new (SwfeditToken *parent, guint tag, SwfdecBuffer *buffer) -{ - SwfeditTag *item; - const SwfeditTagDefinition *def; - - g_return_val_if_fail (SWFEDIT_IS_TOKEN (parent), NULL); - - item = g_object_new (SWFEDIT_TYPE_TAG, NULL); - item->tag = tag; - SWFEDIT_TOKEN (item)->parent = parent; - def = swfedit_tag_get_definition (tag); - if (def) { - SwfdecBits bits; - swfdec_bits_init (&bits, buffer); - for (;def->name != NULL; def++) { - swfedit_tag_read_tag (SWFEDIT_TOKEN (item), &bits, def); - } - if (swfdec_bits_left (&bits)) { - SWFDEC_WARNING ("%u bytes %u bits left unparsed", - swfdec_bits_left (&bits) / 8, swfdec_bits_left (&bits) % 8); - } - } else { - swfedit_token_add (SWFEDIT_TOKEN (item), "contents", SWFEDIT_TOKEN_BINARY, buffer); - } - return item; -} - diff --git a/test/swfedit_tag.h b/test/swfedit_tag.h deleted file mode 100644 index 2f1d231..0000000 --- a/test/swfedit_tag.h +++ /dev/null @@ -1,83 +0,0 @@ -/* Swfedit - * 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 __SWFEDIT_TAG_H__ -#define __SWFEDIT_TAG_H__ - -#include <libswfdec/swfdec_buffer.h> -#include <libswfdec/swfdec_bits.h> -#include "swfdec_out.h" -#include "swfedit_token.h" - -G_BEGIN_DECLS - -typedef struct _SwfeditTag SwfeditTag; -typedef struct _SwfeditTagClass SwfeditTagClass; -typedef struct _SwfeditTagDefinition SwfeditTagDefinition; - -struct _SwfeditTagDefinition { - const char * name; /* name to use for this field */ - SwfeditTokenType type; /* type of this field */ - guint n_items; /* 1-indexed field to look at for item count (or 0 to use 1 item) */ - gconstpointer hint; /* hint to pass to field when creating */ -}; - -#define SWFEDIT_TYPE_TAG (swfedit_tag_get_type()) -#define SWFEDIT_IS_TAG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFEDIT_TYPE_TAG)) -#define SWFEDIT_IS_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFEDIT_TYPE_TAG)) -#define SWFEDIT_TAG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFEDIT_TYPE_TAG, SwfeditTag)) -#define SWFEDIT_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFEDIT_TYPE_TAG, SwfeditTagClass)) -#define SWFEDIT_TAG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFEDIT_TYPE_TAG, SwfeditTagClass)) - -struct _SwfeditTag { - SwfeditToken token; - - guint tag; /* tag type */ -}; - -struct _SwfeditTagClass { - SwfeditTokenClass token_class; -}; - -GType swfedit_tag_get_type (void); - -SwfeditTag * swfedit_tag_new (SwfeditToken * parent, - guint tag, - SwfdecBuffer * buffer); - -SwfdecBuffer * swfedit_tag_write (SwfeditToken * token); -void swfedit_tag_write_token (SwfeditToken * token, - SwfdecOut * out, - guint i); -void swfedit_tag_add_token (SwfeditToken * token, - const char * name, - SwfeditTokenType type, - gconstpointer hint); -void swfedit_tag_read_token (SwfeditToken * token, - SwfdecBits * bits, - const char * name, - SwfeditTokenType type, - gconstpointer hint); -void swfedit_tag_read_tag (SwfeditToken * token, - SwfdecBits * bits, - const SwfeditTagDefinition *def); - -G_END_DECLS - -#endif diff --git a/test/swfedit_token.c b/test/swfedit_token.c deleted file mode 100644 index 34496df..0000000 --- a/test/swfedit_token.c +++ /dev/null @@ -1,797 +0,0 @@ -/* Swfedit - * 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, to_string 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 <stdlib.h> -#include <string.h> -#include <gtk/gtk.h> -#include <libswfdec/swfdec_buffer.h> -#include <libswfdec/swfdec_color.h> -#include <libswfdec/swfdec_script_internal.h> -#include "swfedit_token.h" - -/*** CONVERTERS ***/ - -static gboolean -swfedit_parse_hex (const char *s, guint *result) -{ - guint byte; - - if (s[0] >= '0' && s[0] <= '9') - byte = s[0] - '0'; - else if (s[0] >= 'a' && s[0] <= 'f') - byte = s[0] + 10 - 'a'; - else if (s[0] >= 'A' && s[0] <= 'F') - byte = s[0] + 10 - 'A'; - else - return FALSE; - s++; - byte *= 16; - if (s[0] >= '0' && s[0] <= '9') - byte += s[0] - '0'; - else if (s[0] >= 'a' && s[0] <= 'f') - byte += s[0] + 10 - 'a'; - else if (s[0] >= 'A' && s[0] <= 'F') - byte += s[0] + 10 - 'A'; - else - return FALSE; - *result = byte; - return TRUE; -} - -static gpointer -swfedit_binary_new (void) -{ - return swfdec_buffer_new (); -} - -static gboolean -swfedit_binary_from_string (const char *s, gpointer* result) -{ - GByteArray *array = g_byte_array_new (); - guint byte; - guint8 add; - - while (g_ascii_isspace (*s)) s++; - do { - if (!swfedit_parse_hex (s, &byte)) - break; - s += 2; - add = byte; - g_byte_array_append (array, &add, 1); - while (g_ascii_isspace (*s)) s++; - } while (*s != '\0'); - if (*s == '\0') { - SwfdecBuffer *buffer = swfdec_buffer_new (); - buffer->length = array->len; - buffer->data = array->data; - g_byte_array_free (array, FALSE); - *result = buffer; - return TRUE; - } - g_byte_array_free (array, TRUE); - return FALSE; -} - -static char * -swfedit_binary_to_string (gconstpointer value) -{ - guint i; - const SwfdecBuffer *buffer = value; - GString *string = g_string_new (""); - - for (i = 0; i < buffer->length; i++) { - if (i && i % 4 == 0) - g_string_append_c (string, ' '); - g_string_append_printf (string, "%02X", buffer->data[i]); - } - return g_string_free (string, FALSE); -} - -static gboolean -swfedit_bit_from_string (const char *s, gpointer* result) -{ - if (s[0] == '1' && s[1] == '\0') - *result = GUINT_TO_POINTER (1); - else if (s[0] == '0' && s[1] == '\0') - *result = GUINT_TO_POINTER (0); - else - return FALSE; - return TRUE; -} - -static char * -swfedit_bit_to_string (gconstpointer value) -{ - return g_strdup (value ? "1" : "0"); -} - -static gboolean -swfedit_from_string_unsigned (const char *s, gulong max, gpointer* result) -{ - char *end; - gulong u; - - g_assert (max <= G_MAXUINT); - u = strtoul (s, &end, 10); - if (*end != '\0') - return FALSE; - if (u > max) - return FALSE; - *result = GUINT_TO_POINTER (u); - return TRUE; -} - -static gboolean -swfedit_uint8_from_string (const char *s, gpointer* result) -{ - return swfedit_from_string_unsigned (s, G_MAXUINT8, result); -} - -static gboolean -swfedit_uint16_from_string (const char *s, gpointer* result) -{ - return swfedit_from_string_unsigned (s, G_MAXUINT16, result); -} - -static gboolean -swfedit_uint32_from_string (const char *s, gpointer* result) -{ - return swfedit_from_string_unsigned (s, G_MAXUINT32, result); -} - -static char * -swfedit_to_string_unsigned (gconstpointer value) -{ - return g_strdup_printf ("%u", GPOINTER_TO_UINT (value)); -} - -static char * -swfedit_string_to_string (gconstpointer value) -{ - return g_strdup (value); -} - -static gboolean -swfedit_string_from_string (const char *s, gpointer* result) -{ - *result = g_strdup (s); - return TRUE; -} - -static gpointer -swfedit_rect_new (void) -{ - return g_new0 (SwfdecRect, 1); -} - -static gboolean -swfedit_rect_from_string (const char *s, gpointer* result) -{ - return FALSE; -} - -static char * -swfedit_rect_to_string (gconstpointer value) -{ - const SwfdecRect *rect = value; - - return g_strdup_printf ("%d, %d, %d, %d", (int) rect->x0, (int) rect->y0, - (int) rect->x1, (int) rect->y1); -} - -static gboolean -swfedit_rgb_from_string (const char *s, gpointer* result) -{ - guint r, g, b; - if (strlen (s) != 6) - return FALSE; - if (!swfedit_parse_hex (s, &r)) - return FALSE; - s += 2; - if (!swfedit_parse_hex (s, &g)) - return FALSE; - s += 2; - if (!swfedit_parse_hex (s, &b)) - return FALSE; - *result = GUINT_TO_POINTER (SWFDEC_COLOR_COMBINE (r, g, b, 0xFF)); - return TRUE; -} - -static char * -swfedit_rgb_to_string (gconstpointer value) -{ - guint c = GPOINTER_TO_UINT (value); - - return g_strdup_printf ("%02X%02X%02X", SWFDEC_COLOR_R (c), - SWFDEC_COLOR_G (c), SWFDEC_COLOR_B (c)); -} - -static gboolean -swfedit_rgba_from_string (const char *s, gpointer* result) -{ - guint r, g, b, a; - if (strlen (s) != 8) - return FALSE; - if (!swfedit_parse_hex (s, &a)) - return FALSE; - s += 2; - if (!swfedit_parse_hex (s, &r)) - return FALSE; - s += 2; - if (!swfedit_parse_hex (s, &g)) - return FALSE; - s += 2; - if (!swfedit_parse_hex (s, &b)) - return FALSE; - *result = GUINT_TO_POINTER (SWFDEC_COLOR_COMBINE (r, g, b, a)); - return TRUE; -} - -static char * -swfedit_rgba_to_string (gconstpointer value) -{ - guint c = GPOINTER_TO_UINT (value); - - return g_strdup_printf ("%02X%02X%02X%02X", SWFDEC_COLOR_R (c), - SWFDEC_COLOR_G (c), SWFDEC_COLOR_B (c), SWFDEC_COLOR_A (c)); -} - -static gpointer -swfedit_matrix_new (void) -{ - cairo_matrix_t *matrix = g_new (cairo_matrix_t, 1); - - cairo_matrix_init_identity (matrix); - return matrix; -} - -static gboolean -swfedit_matrix_from_string (const char *s, gpointer* result) -{ - return FALSE; -} - -static char * -swfedit_matrix_to_string (gconstpointer value) -{ - const cairo_matrix_t *mat = value; - - return g_strdup_printf ("{%g %g, %g %g} + {%g, %g}", - mat->xx, mat->xy, mat->yx, mat->yy, mat->x0, mat->y0); -} - -static gpointer -swfedit_ctrans_new (void) -{ - SwfdecColorTransform *trans = g_new (SwfdecColorTransform, 1); - - swfdec_color_transform_init_identity (trans); - return trans; -} - -static gboolean -swfedit_ctrans_from_string (const char *s, gpointer* result) -{ - return FALSE; -} - -static char * -swfedit_ctrans_to_string (gconstpointer value) -{ - const SwfdecColorTransform *trans = value; - - return g_strdup_printf ("{%d %d} {%d %d} {%d %d} {%d %d}", - trans->ra, trans->rb, trans->ga, trans->gb, - trans->ba, trans->bb, trans->aa, trans->ab); -} - -static gpointer -swfedit_script_new (void) -{ - return NULL; -} - -static gboolean -swfedit_script_from_string (const char *s, gpointer* result) -{ - gpointer buffer; - SwfdecScript *script; - - if (!swfedit_binary_from_string (s, &buffer)) { - return FALSE; - } - - script = swfdec_script_new (buffer, "unknown", 6 /* FIXME */); - if (script != NULL) { - *result = script; - return TRUE; - } else { - return FALSE; - } -} - -static char * -swfedit_script_to_string (gconstpointer value) -{ - if (value == NULL) - return g_strdup (""); - else - return swfedit_binary_to_string (((SwfdecScript *) value)->buffer); -} - -static void -swfedit_script_free (gpointer script) -{ - if (script) - swfdec_script_unref (script); -} - -struct { - gpointer (* new) (void); - gboolean (* from_string) (const char *s, gpointer *); - char * (* to_string) (gconstpointer value); - void (* free) (gpointer value); -} converters[SWFEDIT_N_TOKENS] = { - { NULL, NULL, NULL, g_object_unref }, - { swfedit_binary_new, swfedit_binary_from_string, swfedit_binary_to_string, (GDestroyNotify) swfdec_buffer_unref }, - { NULL, swfedit_bit_from_string, swfedit_bit_to_string, NULL }, - { NULL, swfedit_uint8_from_string, swfedit_to_string_unsigned, NULL }, - { NULL, swfedit_uint16_from_string, swfedit_to_string_unsigned, NULL }, - { NULL, swfedit_uint32_from_string, swfedit_to_string_unsigned, NULL }, - { NULL, swfedit_string_from_string, swfedit_string_to_string, g_free }, - { swfedit_rect_new, swfedit_rect_from_string, swfedit_rect_to_string, g_free }, - { NULL, swfedit_rgb_from_string, swfedit_rgb_to_string, NULL }, - { NULL, swfedit_rgba_from_string, swfedit_rgba_to_string, NULL }, - { swfedit_matrix_new, swfedit_matrix_from_string, swfedit_matrix_to_string, g_free }, - { swfedit_ctrans_new, swfedit_ctrans_from_string, swfedit_ctrans_to_string, g_free }, - { swfedit_script_new, swfedit_script_from_string, swfedit_script_to_string, swfedit_script_free }, - { NULL, swfedit_uint32_from_string, swfedit_to_string_unsigned, NULL }, -}; - -gpointer -swfedit_token_new_token (SwfeditTokenType type) -{ - gpointer ret; - - g_assert (type < G_N_ELEMENTS (converters)); - - if (!converters[type].new) - return NULL; - ret = converters[type].new (); - return ret; -} - -/*** GTK_TREE_MODEL ***/ - -#if 0 -# define REPORT g_print ("%s\n", G_STRFUNC) -#else -# define REPORT -#endif -static GtkTreeModelFlags -swfedit_token_get_flags (GtkTreeModel *tree_model) -{ - REPORT; - return 0; -} - -static gint -swfedit_token_get_n_columns (GtkTreeModel *tree_model) -{ - SwfeditToken *token = SWFEDIT_TOKEN (tree_model); - - REPORT; - return token->tokens->len; -} - -static GType -swfedit_token_get_column_type (GtkTreeModel *tree_model, gint index_) -{ - REPORT; - switch (index_) { - case SWFEDIT_COLUMN_NAME: - return G_TYPE_STRING; - case SWFEDIT_COLUMN_VALUE_VISIBLE: - return G_TYPE_BOOLEAN; - case SWFEDIT_COLUMN_VALUE_EDITABLE: - return G_TYPE_BOOLEAN; - case SWFEDIT_COLUMN_VALUE: - return G_TYPE_STRING; - default: - break; - } - g_assert_not_reached (); - return G_TYPE_NONE; -} - -static gboolean -swfedit_token_get_iter (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path) -{ - SwfeditToken *token = SWFEDIT_TOKEN (tree_model); - guint i = gtk_tree_path_get_indices (path)[0]; - SwfeditTokenEntry *entry; - - REPORT; - if (i > token->tokens->len) - return FALSE; - entry = &g_array_index (token->tokens, SwfeditTokenEntry, i); - if (gtk_tree_path_get_depth (path) > 1) { - GtkTreePath *new; - int j; - int *indices; - gboolean ret; - - if (entry->type != SWFEDIT_TOKEN_OBJECT) - return FALSE; - new = gtk_tree_path_new (); - indices = gtk_tree_path_get_indices (path); - for (j = 1; j < gtk_tree_path_get_depth (path); j++) { - gtk_tree_path_append_index (new, indices[j]); - } - ret = swfedit_token_get_iter (GTK_TREE_MODEL (entry->value), iter, new); - gtk_tree_path_free (new); - return ret; - } else { - iter->stamp = 0; /* FIXME */ - iter->user_data = token; - iter->user_data2 = GINT_TO_POINTER (i); - return TRUE; - } -} - -static GtkTreePath * -swfedit_token_get_path (GtkTreeModel *tree_model, GtkTreeIter *iter) -{ - SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data); - GtkTreePath *path = gtk_tree_path_new_from_indices (GPOINTER_TO_INT (iter->user_data2), -1); - - REPORT; - while (token->parent) { - guint i; - SwfeditToken *parent = token->parent; - for (i = 0; i < parent->tokens->len; i++) { - SwfeditTokenEntry *entry = &g_array_index (parent->tokens, SwfeditTokenEntry, i); - if (entry->type != SWFEDIT_TOKEN_OBJECT) - continue; - if (entry->value == token) - break; - } - gtk_tree_path_prepend_index (path, i); - token = parent; - } - return path; -} - -static void -swfedit_token_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter, - gint column, GValue *value) -{ - SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data); - SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, GPOINTER_TO_INT (iter->user_data2)); - - REPORT; - switch (column) { - case SWFEDIT_COLUMN_NAME: - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, entry->name); - return; - case SWFEDIT_COLUMN_VALUE_VISIBLE: - g_value_init (value, G_TYPE_BOOLEAN); - g_value_set_boolean (value, converters[entry->type].to_string != NULL); - return; - case SWFEDIT_COLUMN_VALUE_EDITABLE: - g_value_init (value, G_TYPE_BOOLEAN); - g_value_set_boolean (value, entry->visible); - return; - case SWFEDIT_COLUMN_VALUE: - g_value_init (value, G_TYPE_STRING); - if (converters[entry->type].to_string) - g_value_take_string (value, converters[entry->type].to_string (entry->value)); - return; - default: - break; - } - g_assert_not_reached (); -} - -static gboolean -swfedit_token_iter_next (GtkTreeModel *tree_model, GtkTreeIter *iter) -{ - SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data); - int i; - - REPORT; - i = GPOINTER_TO_INT (iter->user_data2) + 1; - if ((guint) i >= token->tokens->len) - return FALSE; - - iter->user_data2 = GINT_TO_POINTER (i); - return TRUE; -} - -static gboolean -swfedit_token_iter_children (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent) -{ - SwfeditToken *token; - SwfeditTokenEntry *entry; - - REPORT; - if (parent) { - token = SWFEDIT_TOKEN (parent->user_data); - entry = &g_array_index (token->tokens, SwfeditTokenEntry, GPOINTER_TO_INT (parent->user_data2)); - if (entry->type != SWFEDIT_TOKEN_OBJECT) - return FALSE; - token = entry->value; - } else { - token = SWFEDIT_TOKEN (tree_model); - } - if (token->tokens->len == 0) - return FALSE; - iter->stamp = 0; /* FIXME */ - iter->user_data = token; - iter->user_data2 = GINT_TO_POINTER (0); - return TRUE; -} - -static gboolean -swfedit_token_iter_has_child (GtkTreeModel *tree_model, GtkTreeIter *iter) -{ - SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data); - SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, GPOINTER_TO_INT (iter->user_data2)); - - REPORT; - return entry->type == SWFEDIT_TOKEN_OBJECT && SWFEDIT_TOKEN (entry->value)->tokens->len > 0; -} - -static gint -swfedit_token_iter_n_children (GtkTreeModel *tree_model, GtkTreeIter *iter) -{ - SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data); - SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, GPOINTER_TO_INT (iter->user_data2)); - - REPORT; - if (entry->type != SWFEDIT_TOKEN_OBJECT) - return 0; - - token = entry->value; - return token->tokens->len; -} - -static gboolean -swfedit_token_iter_nth_child (GtkTreeModel *tree_model, GtkTreeIter *iter, - GtkTreeIter *parent, gint n) -{ - SwfeditToken *token; - SwfeditTokenEntry *entry; - - REPORT; - if (parent) { - token = SWFEDIT_TOKEN (parent->user_data); - entry = &g_array_index (token->tokens, SwfeditTokenEntry, GPOINTER_TO_INT (parent->user_data2)); - - if (entry->type != SWFEDIT_TOKEN_OBJECT) - return FALSE; - - token = entry->value; - } else { - token = SWFEDIT_TOKEN (tree_model); - } - if ((guint) n >= token->tokens->len) - return FALSE; - iter->stamp = 0; /* FIXME */ - iter->user_data = token; - iter->user_data2 = GINT_TO_POINTER (n); - return TRUE; -} - -static gboolean -swfedit_token_iter_parent (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child) -{ - guint i; - SwfeditToken *token = SWFEDIT_TOKEN (child->user_data); - SwfeditToken *parent = token->parent; - - REPORT; - if (parent == NULL) - return FALSE; - - for (i = 0; i < parent->tokens->len; i++) { - SwfeditTokenEntry *entry = &g_array_index (parent->tokens, SwfeditTokenEntry, i); - if (entry->type != SWFEDIT_TOKEN_OBJECT) - continue; - if (entry->value == token) - break; - } - iter->stamp = 0; /* FIXME */ - iter->user_data = parent; - iter->user_data2 = GINT_TO_POINTER (i); - return TRUE; -} - -static void -swfedit_token_tree_model_init (GtkTreeModelIface *iface) -{ - iface->get_flags = swfedit_token_get_flags; - iface->get_n_columns = swfedit_token_get_n_columns; - iface->get_column_type = swfedit_token_get_column_type; - iface->get_iter = swfedit_token_get_iter; - iface->get_path = swfedit_token_get_path; - iface->get_value = swfedit_token_get_value; - iface->iter_next = swfedit_token_iter_next; - iface->iter_children = swfedit_token_iter_children; - iface->iter_has_child = swfedit_token_iter_has_child; - iface->iter_n_children = swfedit_token_iter_n_children; - iface->iter_nth_child = swfedit_token_iter_nth_child; - iface->iter_parent = swfedit_token_iter_parent; -} - -/*** SWFEDIT_TOKEN ***/ - -G_DEFINE_TYPE_WITH_CODE (SwfeditToken, swfedit_token, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL, swfedit_token_tree_model_init)) - -static void -swfedit_token_dispose (GObject *object) -{ - SwfeditToken *token = SWFEDIT_TOKEN (object); - guint i; - - for (i = 0; i < token->tokens->len; i++) { - SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, i); - g_free (entry->name); - if (converters[entry->type].free) - converters[entry->type].free (entry->value); - } - g_array_free (token->tokens, TRUE); - - G_OBJECT_CLASS (swfedit_token_parent_class)->dispose (object); -} - -static void -swfedit_token_class_init (SwfeditTokenClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = swfedit_token_dispose; -} - -static void -swfedit_token_init (SwfeditToken *token) -{ - token->tokens = g_array_new (FALSE, FALSE, sizeof (SwfeditTokenEntry)); -} - -SwfeditToken * -swfedit_token_new (void) -{ - SwfeditToken *token; - - token = g_object_new (SWFEDIT_TYPE_TOKEN, NULL); - return token; -} - -void -swfedit_token_add (SwfeditToken *token, const char *name, SwfeditTokenType type, - gpointer value) -{ - SwfeditTokenEntry entry = { NULL, type, value, TRUE }; - - g_return_if_fail (SWFEDIT_IS_TOKEN (token)); - g_return_if_fail (name != NULL); - g_return_if_fail (type < SWFEDIT_N_TOKENS); - - g_assert (type != SWFEDIT_TOKEN_OBJECT || value != NULL); - entry.name = g_strdup (name); - g_array_append_val (token->tokens, entry); -} - -void -swfedit_token_set (SwfeditToken *token, guint i, gpointer value) -{ - SwfeditTokenClass *klass; - SwfeditTokenEntry *entry; - GtkTreePath *path; - SwfeditToken *model; - GtkTreeIter iter; - - g_return_if_fail (SWFEDIT_IS_TOKEN (token)); - g_return_if_fail (i < token->tokens->len); - - entry = &g_array_index (token->tokens, SwfeditTokenEntry, i); - if (converters[entry->type].free != NULL) - converters[entry->type].free (entry->value); - entry->value = value; - klass = SWFEDIT_TOKEN_GET_CLASS (token); - if (klass->changed) - klass->changed (token, i); - - model = token; - while (model->parent) - model = model->parent; - iter.user_data = token; - iter.user_data2 = GUINT_TO_POINTER (i); - path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter); - gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter); - gtk_tree_path_free (path); -} - -void -swfedit_token_set_iter (SwfeditToken *token, GtkTreeIter *iter, const char *value) -{ - SwfeditTokenClass *klass; - GtkTreeModel *model; - SwfeditTokenEntry *entry; - guint i; - gpointer new; - GtkTreePath *path; - - g_return_if_fail (SWFEDIT_IS_TOKEN (token)); - g_return_if_fail (iter != NULL); - g_return_if_fail (value != NULL); - - model = GTK_TREE_MODEL (token); - token = iter->user_data; - i = GPOINTER_TO_UINT (iter->user_data2); - entry = &g_array_index (token->tokens, SwfeditTokenEntry, i); - if (converters[entry->type].from_string == NULL) - return; - if (!converters[entry->type].from_string (value, &new)) - return; - if (converters[entry->type].free != NULL) - converters[entry->type].free (entry->value); - entry->value = new; - klass = SWFEDIT_TOKEN_GET_CLASS (token); - if (klass->changed) - klass->changed (token, i); - - path = gtk_tree_model_get_path (model, iter); - gtk_tree_model_row_changed (model, path, iter); - gtk_tree_path_free (path); -} - -void -swfedit_token_set_visible (SwfeditToken *token, guint i, gboolean visible) -{ - SwfeditTokenEntry *entry; - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; - - g_return_if_fail (SWFEDIT_IS_TOKEN (token)); - g_return_if_fail (i < token->tokens->len); - - entry = &g_array_index (token->tokens, SwfeditTokenEntry, i); - if (entry->visible == visible) - return; - - entry->visible = visible; - iter.stamp = 0; /* FIXME */ - iter.user_data = token; - iter.user_data2 = GINT_TO_POINTER (i); - while (token->parent) - token = token->parent; - model = GTK_TREE_MODEL (token); - path = gtk_tree_model_get_path (model, &iter); - gtk_tree_model_row_changed (model, path, &iter); - gtk_tree_path_free (path); -} diff --git a/test/swfedit_token.h b/test/swfedit_token.h deleted file mode 100644 index 448f4cb..0000000 --- a/test/swfedit_token.h +++ /dev/null @@ -1,109 +0,0 @@ -/* Swfedit - * 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 __SWFEDIT_TOKEN_H__ -#define __SWFEDIT_TOKEN_H__ - -#include <gtk/gtk.h> -#include <libswfdec/swfdec_rect.h> - -G_BEGIN_DECLS - -typedef enum { - SWFEDIT_TOKEN_OBJECT, - SWFEDIT_TOKEN_BINARY, - SWFEDIT_TOKEN_BIT, - SWFEDIT_TOKEN_UINT8, - SWFEDIT_TOKEN_UINT16, - SWFEDIT_TOKEN_UINT32, - SWFEDIT_TOKEN_STRING, - SWFEDIT_TOKEN_RECT, - SWFEDIT_TOKEN_RGB, - SWFEDIT_TOKEN_RGBA, - SWFEDIT_TOKEN_MATRIX, - SWFEDIT_TOKEN_CTRANS, - SWFEDIT_TOKEN_SCRIPT, - SWFEDIT_TOKEN_CLIPEVENTFLAGS, - SWFEDIT_N_TOKENS -} SwfeditTokenType; - -typedef enum { - SWFEDIT_COLUMN_NAME, - SWFEDIT_COLUMN_VALUE_VISIBLE, - SWFEDIT_COLUMN_VALUE, - SWFEDIT_COLUMN_VALUE_EDITABLE -} SwfeditColumn; - -typedef struct _SwfeditTokenEntry SwfeditTokenEntry; - -typedef struct _SwfeditToken SwfeditToken; -typedef struct _SwfeditTokenClass SwfeditTokenClass; - -#define SWFEDIT_TYPE_TOKEN (swfedit_token_get_type()) -#define SWFEDIT_IS_TOKEN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFEDIT_TYPE_TOKEN)) -#define SWFEDIT_IS_TOKEN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFEDIT_TYPE_TOKEN)) -#define SWFEDIT_TOKEN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFEDIT_TYPE_TOKEN, SwfeditToken)) -#define SWFEDIT_TOKEN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFEDIT_TYPE_TOKEN, SwfeditTokenClass)) -#define SWFEDIT_TOKEN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFEDIT_TYPE_TOKEN, SwfeditTokenClass)) - -struct _SwfeditTokenEntry { - char * name; - SwfeditTokenType type; - gpointer value; - gboolean visible; -}; - -struct _SwfeditToken { - GObject object; - - SwfeditToken * parent; /* parent of this token or NULL */ - gchar * name; /* name of token */ - GArray * tokens; /* of SwfeditTokenEntry */ -}; - -struct _SwfeditTokenClass { - GObjectClass object_class; - - void (* changed) (SwfeditToken * token, - guint id); -}; - -GType swfedit_token_get_type (void); - -gpointer swfedit_token_new_token (SwfeditTokenType type); - -SwfeditToken * swfedit_token_new (void); -void swfedit_token_add (SwfeditToken * token, - const char * name, - SwfeditTokenType type, - gpointer value); -void swfedit_token_set (SwfeditToken * token, - guint i, - gpointer value); -void swfedit_token_set_iter (SwfeditToken * token, - GtkTreeIter * iter, - const char * value); -void swfedit_token_set_visible (SwfeditToken * token, - guint i, - gboolean visible); - - -G_END_DECLS - -#endif diff --git a/test/swfscript.c b/test/swfscript.c deleted file mode 100644 index 4e2a9e4..0000000 --- a/test/swfscript.c +++ /dev/null @@ -1,298 +0,0 @@ -/* Swfedit - * 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 <gtk/gtk.h> -#include "libswfdec/swfdec_script_internal.h" -#include "swfdec_out.h" -#include "swfedit_file.h" - -/* the stuff we look for */ -guint *add_trace = NULL; - -typedef gboolean ( *SwfeditTokenForeachFunc) (SwfeditToken *token, guint idx, - const char *name, SwfeditTokenType type, gconstpointer value, gpointer data); - -static gboolean -swfedit_token_foreach (SwfeditToken *token, SwfeditTokenForeachFunc func, - gpointer data) -{ - SwfeditTokenEntry *entry; - guint i; - - g_return_val_if_fail (SWFEDIT_IS_TOKEN (token), FALSE); - g_return_val_if_fail (func != NULL, FALSE); - - for (i = 0; i < token->tokens->len; i++) { - entry = &g_array_index (token->tokens, SwfeditTokenEntry, i); - if (!func (token, i, entry->name, entry->type, entry->value, data)) - return FALSE; - if (entry->type == SWFEDIT_TOKEN_OBJECT) { - if (!swfedit_token_foreach (entry->value, func, data)) - return FALSE; - } - } - return TRUE; -} - -typedef struct { - guint offset; /* offset in bytes from start of script */ - guint new_offset; /* new offset in bytes from start of script */ - guint new_actions; /* number of actions in new script */ -} Action; - -typedef struct { - SwfdecScript * script; /* the original script */ - SwfdecOut * out; /* output for new script or NULL when buffer is set */ - SwfdecBuffer * buffer; /* buffer containing new script or NULL while constructing */ - GArray * actions; /* all actions in the script */ -} State; - -static gboolean -action_in_array (guint *array, guint action) -{ - if (array == NULL) - return FALSE; - while (*array != 0) { - if (*array == action) - return TRUE; - array++; - } - return FALSE; -} - -static guint -lookup_offset (GArray *array, guint offset) -{ - guint i; - for (i = 0; i < array->len; i++) { - Action *action = &g_array_index (array, Action, i); - if (action->offset == offset) - return action->new_offset; - } - g_assert_not_reached (); - return 0; -} - -static gboolean -fixup_jumps_foreach (gconstpointer bytecode, guint action, - const guint8 *data, guint len, gpointer user_data) -{ - State *state = user_data; - - if (action == 0x99 || action == 0x9d) { - guint offset = (guint8 *) bytecode - state->script->buffer->data; - guint jump_offset = offset + 5 + GINT16_FROM_LE (*((gint16 *) data)); - offset = lookup_offset (state->actions, offset); - jump_offset = lookup_offset (state->actions, jump_offset); - *((gint16 *) &state->buffer->data[offset + 3]) = - GINT16_TO_LE (jump_offset - offset - 5); - } - if (action == 0x8a || action == 0x8d) { - Action *cur = NULL; /* silence gcc */ - guint id = action == 0x8a ? 2 : 0; - guint i, count; - guint offset = (guint8 *) bytecode - state->script->buffer->data; - for (i = 0; i < state->actions->len; i++) { - cur = &g_array_index (state->actions, Action, i); - if (cur->offset == offset) { - offset = cur->new_offset; - break; - } - } - g_assert (i < state->actions->len); - i = data[id]; - count = cur->new_actions - 1; /* FIXME: only works as long as we append actions */ - while (i > 0) { - cur++; - count += cur->new_actions; - i--; - } - g_assert (count < 256); - state->buffer->data[offset + 3 + id] = count; - } - return TRUE; -} - -static gboolean -modify_script_foreach (gconstpointer bytecode, guint action, - const guint8 *data, guint len, gpointer user_data) -{ - Action next; - State *state = user_data; - - next.offset = (guint8 *) bytecode - state->script->buffer->data; - next.new_offset = swfdec_out_get_bits (state->out) / 8; - next.new_actions = 1; - swfdec_out_put_u8 (state->out, action); - if (action & 0x80) { - swfdec_out_put_u16 (state->out, len); - swfdec_out_put_data (state->out, data, len); - } - if (action_in_array (add_trace, action)) { - swfdec_out_put_u8 (state->out, 0x4c); /* PushDuplicate */ - swfdec_out_put_u8 (state->out, 0x26); /* Trace */ - next.new_actions += 2; - } - g_array_append_val (state->actions, next); - return TRUE; -} - -static gboolean -modify_file (SwfeditToken *token, guint idx, const char *name, - SwfeditTokenType type, gconstpointer value, gpointer data) -{ - Action end; - SwfdecScript *script; - State state; - - if (type != SWFEDIT_TOKEN_SCRIPT) - return TRUE; - - state.script = (SwfdecScript *) value; - state.out = swfdec_out_open (); - state.buffer = NULL; - state.actions = g_array_new (FALSE, FALSE, sizeof (Action)); - swfdec_script_foreach (state.script, modify_script_foreach, &state); - /* compute end offset */ - end.offset = g_array_index (state.actions, Action, state.actions->len - 1).offset; - if (state.script->buffer->data[end.offset] & 0x80) { - end.offset += GUINT16_FROM_LE (*((guint16* ) &state.script->buffer->data[end.offset + 1])) + 3; - } else { - end.offset++; - } - end.new_offset = swfdec_out_get_bits (state.out) / 8; - end.new_actions = 0; - g_array_append_val (state.actions, end); -#if 0 - { - guint i; - for (i = 0; i < state.actions->len; i++) { - Action *action = &g_array_index (state.actions, Action, i); - g_print ("%u %u => %u (%u actions)\n", i, action->offset, - action->new_offset, action->new_actions); - } - } -#endif - /* maybe append 0 byte */ - if (end.offset + 1 == state.script->buffer->length) { - swfdec_out_put_u8 (state.out, 0); - } else { - g_assert (end.offset == state.script->buffer->length); - } - state.buffer = swfdec_out_close (state.out); - state.out = NULL; - swfdec_script_foreach (state.script, fixup_jumps_foreach, &state); - g_array_free (state.actions, TRUE); -#if 0 - g_print ("got a new script in %u bytes - old script was %u bytes\n", - state.buffer->length, state.script->buffer->length); -#endif - script = swfdec_script_new (state.buffer, state.script->name, state.script->version); - g_assert (script); - swfedit_token_set (token, idx, script); - - return TRUE; -} - -static guint * -string_to_action_list (const char *list) -{ - char **actions = g_strsplit (list, ",", -1); - guint *ret; - guint i, len; - - len = g_strv_length (actions); - ret = g_new (guint, len + 1); - ret[len] = 0; - for (i = 0; i < len; i++) { - ret[i] = swfdec_action_get_from_name (actions[i]); - if (ret[i] == 0) { - g_printerr ("No such action \"%s\"\n", actions[i]); - g_free (actions); - g_free (ret); - return NULL; - } - } - g_free (actions); - return ret; -} - -int -main (int argc, char **argv) -{ - SwfeditFile *file; - GError *error = NULL; - char *add_trace_s = NULL; - GOptionEntry options[] = { - { "add-trace", 't', 0, G_OPTION_ARG_STRING, &add_trace_s, "list of actions to trace", "ACTION, ACTION" }, - { NULL } - }; - GOptionContext *ctx; - - ctx = g_option_context_new (""); - g_option_context_add_main_entries (ctx, options, "options"); - g_option_context_add_group (ctx, gtk_get_option_group (TRUE)); - g_option_context_parse (ctx, &argc, &argv, &error); - g_option_context_free (ctx); - if (error) { - g_printerr ("error parsing arguments: %s\n", error->message); - g_error_free (error); - return 1; - } - - if (argc < 2) { - g_printerr ("Usage: %s FILENAME [OUTPUT-FILENAME]\n", argv[0]); - return 1; - } - if (add_trace_s) { - add_trace = string_to_action_list (add_trace_s); - g_free (add_trace_s); - if (add_trace == NULL) - return 1; - } - file = swfedit_file_new (argv[1], &error); - if (file == NULL) { - g_printerr ("error opening file %s: %s\n", argv[1], error->message); - g_error_free (error); - return 1; - } - if (!swfedit_token_foreach (SWFEDIT_TOKEN (file), modify_file, NULL)) { - g_printerr ("modifying file %s failed.\n", argv[1]); - g_object_unref (file); - return 1; - } - g_free (file->filename); - if (argc > 2) { - file->filename = g_strdup (argv[2]); - } else { - file->filename = g_strdup_printf ("%s.out.swf", argv[1]); - } - if (!swfedit_file_save (file, &error)) { - g_printerr ("Error saving file: %s\n", error->message); - g_error_free (error); - } - g_print ("saved modified file to %s\n", file->filename); - g_object_unref (file); - return 0; -} - diff --git a/tools/.gitignore b/tools/.gitignore new file mode 100644 index 0000000..9f6d925 --- /dev/null +++ b/tools/.gitignore @@ -0,0 +1,17 @@ +*~ +.deps +.libs + +Makefile +Makefile.in +*.lo +*.o + +libswfedit.la + +dump +parse +swfdec-extract +swfedit +swfscript +crashfinder diff --git a/tools/Makefile.am b/tools/Makefile.am new file mode 100644 index 0000000..9064878 --- /dev/null +++ b/tools/Makefile.am @@ -0,0 +1,41 @@ +if WITH_GTK +noinst_LTLIBRARIES = libswfedit.la +noinst_PROGRAMS = swfdec-extract dump swfedit swfscript crashfinder +else +noinst_PROGRAMS = swfdec-extract dump crashfinder +endif + +crashfinder_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) +crashfinder_LDFLAGS = $(SWFDEC_LIBS) $(CAIRO_LIBS) +crashfinder_SOURCES = crashfinder.c + +dump_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(CAIRO_CFLAGS) $(PANGO_CFLAGS) +dump_LDFLAGS = $(SWFDEC_LIBS) $(CAIRO_LIBS) $(PANGO_LIBS) + +swfdec_extract_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(CAIRO_CFLAGS) +swfdec_extract_LDFLAGS = $(SWFDEC_LIBS) $(CAIRO_LIBS) + +libswfedit_la_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(GTK_CFLAGS) +libswfedit_la_LDFLAGS = $(SWFDEC_LIBS) $(GTK_LIBS) + +swfedit_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(GTK_CFLAGS) +swfedit_LDFLAGS = $(SWFDEC_LIBS) $(GTK_LIBS) +swfedit_LDADD = libswfedit.la + +swfscript_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(GTK_CFLAGS) +swfscript_LDFLAGS = $(SWFDEC_LIBS) $(GTK_LIBS) +swfscript_LDADD = libswfedit.la + +libswfedit_la_SOURCES = \ + swfdec_out.c \ + swfedit_file.c \ + swfedit_list.c \ + swfedit_tag.c \ + swfedit_token.c + +noinst_HEADERS = \ + swfdec_out.h \ + swfedit_file.h \ + swfedit_list.h \ + swfedit_tag.h \ + swfedit_token.h diff --git a/tools/crashfinder.c b/tools/crashfinder.c new file mode 100644 index 0000000..3c4a4a7 --- /dev/null +++ b/tools/crashfinder.c @@ -0,0 +1,157 @@ +/* Swfdec + * Copyright (C) 2007 Pekka Lampila <pekka.lampila at iki.fi> + * 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 <libswfdec/swfdec.h> + +int +main (int argc, char **argv) +{ + GOptionContext *context; + GError *err; + SwfdecPlayer *player; + SwfdecLoader *loader; + guint i; + cairo_surface_t *surface; + cairo_t *cr; + gboolean aborts; + glong play_per_file = 30; + glong max_per_file = 60; + glong max_per_advance = 10; + GTimer *timer; + char **filenames = NULL; + const GOptionEntry entries[] = { + { + "play-time", 'p', 0, G_OPTION_ARG_INT, &play_per_file, + "How many seconds will be played from each file (default 30)", NULL + }, + { + "max-per-file", '\0', 0, G_OPTION_ARG_INT, &max_per_file, + "Maximum runtime in seconds allowed for each file (default 60)", NULL + }, + { + "max-per-advance", '\0', 0, G_OPTION_ARG_INT, &max_per_advance, + "Maximum runtime in seconds allowed for each advance (default 10)", NULL + }, + { + G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, + NULL, "<INPUT FILE> <OUTPUT FILE>" + }, + { + NULL + } + }; + + // init + swfdec_init (); + + // read command line params + context = g_option_context_new ("Run a Flash file trying to crash Swfdec"); + g_option_context_add_main_entries (context, entries, NULL); + + if (g_option_context_parse (context, &argc, &argv, &err) == FALSE) { + g_printerr ("Couldn't parse command-line options: %s\n", err->message); + g_error_free (err); + return 1; + } + + if (filenames == NULL || g_strv_length (filenames) < 1) { + g_printerr ("At least one input filename is required\n"); + return 1; + } + + // make them milliseconds + play_per_file *= 1000; + max_per_file *= 1000; + max_per_advance *= 1000; + + // create surface + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1); + cr = cairo_create (surface); + + aborts = FALSE; + for (i = 0; i < g_strv_length (filenames); i++) + { + glong played, advance, elapsed; + + g_print ("Running: %s\n", filenames[i]); + + // start timer + timer = g_timer_new (); + + // create player + loader = swfdec_file_loader_new (filenames[i]); + player = swfdec_player_new (NULL); + + if (loader->error) { + g_printerr ("Error loading %s: %s\n", filenames[i], loader->error); + g_object_unref (loader); + continue; + } + + swfdec_player_set_loader (player, loader); + + // loop until we have played what we wanted, or timelimit is hit + played = 0; + elapsed = 0; + while (played < play_per_file && + !swfdec_as_context_is_aborted (SWFDEC_AS_CONTEXT (player))) + { + elapsed = (glong)(g_timer_elapsed (timer, NULL) * 1000); + if (elapsed >= max_per_file) + break; + swfdec_player_set_maximum_runtime (player, + MIN (max_per_advance, max_per_file - elapsed)); + + advance = swfdec_player_get_next_event (player); + if (advance == -1) + break; + swfdec_player_advance (player, advance); + + swfdec_player_render (player, cr, 0, 0, 0, 0); + + played += advance; + } + + if (elapsed >= max_per_file || + swfdec_as_context_is_aborted (SWFDEC_AS_CONTEXT (player))) { + g_print ("Aborted: %s\n", filenames[i]); + aborts = TRUE; + } else { + g_print ("Finished: %s\n", filenames[i]); + } + + // clean up + g_object_unref (player); + g_timer_destroy (timer); + } + + cairo_destroy (cr); + cairo_surface_destroy (surface); + + if (aborts) { + return 1; + } else { + return 0; + } +} diff --git a/tools/dump.c b/tools/dump.c new file mode 100644 index 0000000..efea56d --- /dev/null +++ b/tools/dump.c @@ -0,0 +1,448 @@ +/* Swfdec + * Copyright (C) 2003-2006 David Schleef <ds at schleef.org> + * 2005-2006 Eric Anholt <eric at anholt.net> + * 2006-2007 Benjamin Otte <otte at gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * 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 <stdio.h> +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <glib.h> +#include <glib-object.h> +#include <libswfdec/swfdec.h> +#include <libswfdec/swfdec_button.h> +#include <libswfdec/swfdec_text_field.h> +#include <libswfdec/swfdec_font.h> +#include <libswfdec/swfdec_image.h> +#include <libswfdec/swfdec_movie.h> +#include <libswfdec/swfdec_player_internal.h> +#include <libswfdec/swfdec_sprite.h> +#include <libswfdec/swfdec_shape.h> +#include <libswfdec/swfdec_sound.h> +#include <libswfdec/swfdec_swf_decoder.h> +#include <libswfdec/swfdec_resource.h> +#include <libswfdec/swfdec_tag.h> +#include <libswfdec/swfdec_text.h> + +static gboolean verbose = FALSE; + +static const char * +get_audio_format_name (guint codec) +{ + switch (codec) { + case SWFDEC_AUDIO_CODEC_ADPCM: + return "ADPCM"; + case SWFDEC_AUDIO_CODEC_MP3: + return "MP3"; + case SWFDEC_AUDIO_CODEC_UNCOMPRESSED: + return "uncompressed"; + case SWFDEC_AUDIO_CODEC_NELLYMOSER: + return "Nellymoser"; + default: + return "Unknown"; + } +} + +static void +dump_sound (SwfdecSound *sound) +{ + g_print (" codec: %s\n", get_audio_format_name (sound->codec)); + if (verbose) { + g_print (" format: %s\n", swfdec_audio_format_to_string (sound->format)); + g_print (" samples: %u (%gs)\n", sound->n_samples, + (double) sound->n_samples / swfdec_audio_format_get_rate (sound->format)); + } +} + +static void +dump_sprite (SwfdecSwfDecoder *dec, SwfdecSprite *s) +{ + if (!verbose) { + g_print (" %u frames\n", s->n_frames); + } else { + guint i, j, tag; + SwfdecBuffer *buffer; + SwfdecSound *sound = NULL; + + for (i = 0; i < s->n_frames; i++) { + SwfdecSpriteFrame *frame = &s->frames[i]; + if (frame->sound_head != sound && + frame->sound_block != NULL) { + sound = frame->sound_head; + for (j = i; j < s->n_frames; j++) { + SwfdecSpriteFrame *cur = &s->frames[i]; + if (cur->sound_head != sound) + break; + } + if (sound) + g_print (" %4u -%4u sound: %s %s\n", i, j, + get_audio_format_name (sound->codec), + swfdec_audio_format_to_string (sound->format)); + } + } + + j = 0; + for (i = 0; ; i++) { + if (!swfdec_sprite_get_action (s, i, &tag, &buffer)) + break; + switch (tag) { + case SWFDEC_TAG_DOACTION: + g_print (" %4u script\n", j); + break; + case SWFDEC_TAG_PLACEOBJECT2: + case SWFDEC_TAG_PLACEOBJECT3: + { + SwfdecBits bits; + gboolean has_char, is_move; + guint depth; + + swfdec_bits_init (&bits, buffer); + swfdec_bits_getbits (&bits, 6); + has_char = swfdec_bits_getbit (&bits); + is_move = swfdec_bits_getbit (&bits); + if (tag == SWFDEC_TAG_PLACEOBJECT3) + swfdec_bits_get_u8 (&bits); + depth = swfdec_bits_get_u16 (&bits); + g_print (" %4u %5u %s", j, depth, is_move ? "move" : "place"); + if (has_char) { + SwfdecCharacter *c; + c = swfdec_swf_decoder_get_character (dec, swfdec_bits_get_u16 (&bits)); + if (c) + g_print (" %s %u", G_OBJECT_TYPE_NAME (c), c->id); + } + g_print ("\n"); + } + break; + case SWFDEC_TAG_REMOVEOBJECT: + case SWFDEC_TAG_REMOVEOBJECT2: + { + SwfdecBits bits; + swfdec_bits_init (&bits, buffer); + if (tag == SWFDEC_TAG_REMOVEOBJECT) + swfdec_bits_get_u16 (&bits); + g_print (" %4u %5u remove\n", j, swfdec_bits_get_u16 (&bits)); + } + break; + case SWFDEC_TAG_SHOWFRAME: + j++; + break; + case SWFDEC_TAG_STARTSOUND: + /* FIXME add info about what sound etc */ + g_print (" %4u start sound\n", j); + break; + case SWFDEC_TAG_EXPORTASSETS: + g_print (" %4u export\n", j); + break; + case SWFDEC_TAG_DOINITACTION: + g_print (" %4u init action\n", j); + break; + default: + g_assert_not_reached (); + } + } + } +} + +static void +dump_path (cairo_path_t *path) +{ + int i; + cairo_path_data_t *data = path->data; + const char *name; + + for (i = 0; i < path->num_data; i++) { + name = NULL; + switch (data[i].header.type) { + case CAIRO_PATH_CURVE_TO: + g_print (" curve %g %g (%g %g . %g %g)\n", + data[i + 3].point.x, data[i + 3].point.y, + data[i + 1].point.x, data[i + 1].point.y, + data[i + 2].point.x, data[i + 2].point.y); + i += 3; + break; + case CAIRO_PATH_LINE_TO: + name = "line "; + case CAIRO_PATH_MOVE_TO: + if (!name) + name = "move "; + i++; + g_print (" %s %g %g\n", name, data[i].point.x, data[i].point.y); + break; + case CAIRO_PATH_CLOSE_PATH: + g_print (" close\n"); + break; + default: + g_assert_not_reached (); + break; + } + } +} + +static void +dump_shape (SwfdecShape *shape) +{ + GSList *walk; + + for (walk = shape->draws; walk; walk = walk->next) { + if (SWFDEC_IS_PATTERN (walk->data)) { + SwfdecPattern *pattern = walk->data; + char *str = swfdec_pattern_to_string (pattern); + g_print ("%s\n", str); + g_free (str); + if (verbose) { + g_print (" %g %g %g %g %g %g\n", + pattern->start_transform.xx, pattern->start_transform.xy, + pattern->start_transform.yx, pattern->start_transform.yy, + pattern->start_transform.x0, pattern->start_transform.y0); + } + } else if (SWFDEC_IS_STROKE (walk->data)) { + SwfdecStroke *line = walk->data; + g_print ("line (width %u, color #%08X)\n", line->start_width, line->start_color); + } else { + g_print ("not filled\n"); + } + if (verbose) { + dump_path (&SWFDEC_DRAW (walk->data)->path); + } + } +} + +static void +dump_text_field (SwfdecTextField *text) +{ + g_print (" %s\n", text->input ? text->input : ""); + if (verbose) { + if (text->variable) + g_print (" variable %s\n", text->variable); + else + g_print (" no variable\n"); + } +} + +static void +dump_text (SwfdecText *text) +{ + guint i; + gunichar2 uni[text->glyphs->len]; + char *s; + + for (i = 0; i < text->glyphs->len; i++) { + SwfdecTextGlyph *glyph = &g_array_index (text->glyphs, SwfdecTextGlyph, i); + uni[i] = g_array_index (glyph->font->glyphs, SwfdecFontEntry, glyph->glyph).value; + if (uni[i] == 0) + goto fallback; + } + s = g_utf16_to_utf8 (uni, text->glyphs->len, NULL, NULL, NULL); + if (s == NULL) + goto fallback; + g_print (" text: %s\n", s); + g_free (s); + return; + +fallback: + g_print (" %u characters\n", text->glyphs->len); +} + +static void +dump_font (SwfdecFont *font) +{ + unsigned int i; + if (font->name) + g_print (" %s\n", font->name); + g_print (" %u characters\n", font->glyphs->len); + if (verbose) { + for (i = 0; i < font->glyphs->len; i++) { + gunichar2 c = g_array_index (font->glyphs, SwfdecFontEntry, i).value; + char *s; + if (c == 0 || (s = g_utf16_to_utf8 (&c, 1, NULL, NULL, NULL)) == NULL) { + g_print (" "); + } else { + g_print ("%s ", s); + g_free (s); + } + } + g_print ("\n"); + } +} + +static void +dump_button (SwfdecButton *button) +{ +} + +static const char * +get_image_type_name (SwfdecImageType type) +{ + switch (type) { + case SWFDEC_IMAGE_TYPE_JPEG: + return "JPEG with global table"; + case SWFDEC_IMAGE_TYPE_JPEG2: + return "JPEG"; + case SWFDEC_IMAGE_TYPE_JPEG3: + return "JPEG with alpha"; + case SWFDEC_IMAGE_TYPE_LOSSLESS: + 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 (); + return "Unknown"; + } +} + +static void +dump_image (SwfdecImage *image) +{ + cairo_surface_destroy (swfdec_image_create_surface (image)); + g_print (" %s %u x %u\n", get_image_type_name (image->type), + image->width, image->height); +} + +static void +dump_object (gpointer value, gpointer dec) +{ + SwfdecCharacter *c = value; + + g_print ("%d: %s\n", c->id, G_OBJECT_TYPE_NAME (c)); + if (verbose && SWFDEC_IS_GRAPHIC (c)) { + SwfdecGraphic *graphic = SWFDEC_GRAPHIC (c); + g_print (" extents: %g %g %g %g\n", graphic->extents.x0, graphic->extents.y0, + graphic->extents.x1, graphic->extents.y1); + } + if (SWFDEC_IS_IMAGE (c)) { + dump_image (SWFDEC_IMAGE (c)); + } + if (SWFDEC_IS_SPRITE (c)) { + dump_sprite (dec, SWFDEC_SPRITE (c)); + } + if (SWFDEC_IS_SHAPE(c)) { + dump_shape(SWFDEC_SHAPE(c)); + } + if (SWFDEC_IS_TEXT (c)) { + dump_text (SWFDEC_TEXT (c)); + } + if (SWFDEC_IS_TEXT_FIELD (c)) { + dump_text_field (SWFDEC_TEXT_FIELD (c)); + } + if (SWFDEC_IS_FONT (c)) { + dump_font (SWFDEC_FONT (c)); + } + if (SWFDEC_IS_BUTTON (c)) { + dump_button (SWFDEC_BUTTON (c)); + } + if (SWFDEC_IS_SOUND (c)) { + dump_sound (SWFDEC_SOUND (c)); + } +} + +static void +enqueue (gpointer key, gpointer value, gpointer listp) +{ + GList **list = listp; + + *list = g_list_prepend (*list, value); +} + +static int +sort_by_id (gconstpointer a, gconstpointer b) +{ + if (SWFDEC_CHARACTER (a)->id < SWFDEC_CHARACTER (b)->id) + return -1; + return 1; +} + +int +main (int argc, char *argv[]) +{ + SwfdecSwfDecoder *s; + SwfdecPlayer *player; + GError *error = NULL; + GOptionEntry options[] = { + { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "bew verbose", NULL }, + { NULL } + }; + GOptionContext *ctx; + GList *list = NULL; + + ctx = g_option_context_new (""); + g_option_context_add_main_entries (ctx, options, "options"); + g_option_context_parse (ctx, &argc, &argv, &error); + g_option_context_free (ctx); + if (error) { + g_printerr ("Error parsing command line arguments: %s\n", error->message); + g_error_free (error); + return 1; + } + + swfdec_init(); + + if(argc < 2){ + g_print ("usage: %s [OPTIONS] file\n", argv[0]); + return 0; + } + + player = swfdec_player_new_from_file (argv[1]); + if (player->priv->resource->loader->error) { + g_printerr ("Couldn't open file \"%s\": %s\n", argv[1], player->priv->resource->loader->error); + g_object_unref (player); + return 1; + } + /* FIXME: HACK! */ + swfdec_player_advance (player, 0); + if (!swfdec_player_is_initialized (player)) { + g_printerr ("File \"%s\" is not a SWF file\n", argv[1]); + g_object_unref (player); + player = NULL; + return 1; + } + s = (SwfdecSwfDecoder *) SWFDEC_MOVIE (player->priv->roots->data)->resource->decoder; + /* FIXME: can happen after a _root.loadMovie() call */ + if (!SWFDEC_IS_SWF_DECODER (s)) { + g_printerr ("Movie already unloaded from \"%s\"\n", argv[1]); + g_object_unref (player); + player = NULL; + return 1; + } + + g_print ("file:\n"); + g_print (" version: %d\n", s->version); + g_print (" rate : %g fps\n", SWFDEC_DECODER (s)->rate / 256.0); + g_print (" size : %ux%u pixels\n", SWFDEC_DECODER (s)->width, SWFDEC_DECODER (s)->height); + g_print ("objects:\n"); + g_hash_table_foreach (s->characters, enqueue, &list); + list = g_list_sort (list, sort_by_id); + g_list_foreach (list, dump_object, s); + g_list_free (list); + + g_print ("main sprite:\n"); + dump_sprite (s, s->main_sprite); + g_object_unref (player); + s = NULL; + player = NULL; + + return 0; +} + diff --git a/tools/swfdec-extract.c b/tools/swfdec-extract.c new file mode 100644 index 0000000..3edfd25 --- /dev/null +++ b/tools/swfdec-extract.c @@ -0,0 +1,301 @@ +/* Swfdec + * Copyright (C) 2006 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 <math.h> +#include <stdlib.h> +#include <string.h> +#include <cairo.h> +#ifdef CAIRO_HAS_SVG_SURFACE +# include <cairo-svg.h> +#endif +#ifdef CAIRO_HAS_PDF_SURFACE +# include <cairo-pdf.h> +#endif +#include <libswfdec/swfdec.h> +#include <libswfdec/swfdec_audio_stream.h> +#include <libswfdec/swfdec_button.h> +#include <libswfdec/swfdec_graphic.h> +#include <libswfdec/swfdec_image.h> +#include <libswfdec/swfdec_player_internal.h> +#include <libswfdec/swfdec_sound.h> +#include <libswfdec/swfdec_sprite.h> +#include <libswfdec/swfdec_sprite_movie.h> +#include <libswfdec/swfdec_swf_decoder.h> +#include <libswfdec/swfdec_resource.h> + +static SwfdecBuffer * +encode_wav (SwfdecBuffer *buffer, SwfdecAudioFormat format) +{ + SwfdecBuffer *wav = swfdec_buffer_new_and_alloc (buffer->length + 44); + unsigned char *data; + guint i; + + data = wav->data; + /* FIXME: too much magic in this memmove */ + memmove (data, "RIFF----WAVEfmt \020\0\0\0" + "\001\0ccRRRRbbbbAAbbdata", 40); + *(guint32 *) (void *) &data[4] = GUINT32_TO_LE (buffer->length + 36); + *(guint16 *) (void *) &data[22] = GUINT16_TO_LE (swfdec_audio_format_get_channels (format)); + *(guint32 *) (void *) &data[24] = GUINT32_TO_LE (swfdec_audio_format_get_rate (format)); + /* bits per sample */ + i = swfdec_audio_format_is_16bit (format) ? 2 : 1; + *(guint16 *) (void *) &data[34] = GUINT16_TO_LE (i * 8); + /* block align */ + i *= swfdec_audio_format_get_channels (format); + *(guint16 *) (void *) &data[32] = GUINT16_TO_LE (i); + /* bytes per second */ + i *= swfdec_audio_format_get_rate (format); + *(guint32 *) (void *) &data[28] = GUINT32_TO_LE (i); + *(guint32 *) (void *) &data[40] = GUINT32_TO_LE (buffer->length); + data += 44; + if (swfdec_audio_format_is_16bit (format)) { + for (i = 0; i < buffer->length; i += 2) { + *(gint16 *) (void *) (data + i) = GINT16_TO_LE (*(gint16* ) (void *) (buffer->data + i)); + } + } else { + memcpy (data, buffer->data, buffer->length); + } + return wav; +} + +static gboolean +export_sound (SwfdecSound *sound, const char *filename) +{ + GError *error = NULL; + SwfdecBuffer *wav, *buffer; + SwfdecAudioFormat format; + + /* try to render the sound, that should decode it. */ + buffer = swfdec_sound_get_decoded (sound, &format); + if (buffer == NULL) { + g_printerr ("Couldn't decode sound. For extraction of streams extract the sprite.\n"); + return FALSE; + } + wav = encode_wav (buffer, format); + if (!g_file_set_contents (filename, (char *) wav->data, + wav->length, &error)) { + g_printerr ("Couldn't save sound to file \"%s\": %s\n", filename, error->message); + swfdec_buffer_unref (wav); + g_error_free (error); + return FALSE; + } + swfdec_buffer_unref (wav); + return TRUE; +} + +static gboolean +export_sprite_sound (SwfdecSprite *sprite, const char *filename) +{ + GError *error = NULL; + guint i, depth; + SwfdecAudio *audio; + SwfdecBufferQueue *queue; + SwfdecBuffer *buffer, *wav; + + for (i = 0; i < sprite->n_frames; i++) { + if (sprite->frames[i].sound_head) + break; + } + if (i >= sprite->n_frames) { + g_printerr ("No sound in sprite %u\n", SWFDEC_CHARACTER (sprite)->id); + return FALSE; + } + audio = swfdec_audio_stream_new (NULL, sprite, i); + i = 4096; + queue = swfdec_buffer_queue_new (); + while (i > 0) { + buffer = swfdec_buffer_new (); + buffer->data = g_malloc0 (i * 4); + buffer->length = i * 4; +#if 0 + if (i > 1234) { + swfdec_audio_render (audio, (gint16 *) buffer->data, 0, 1234); + swfdec_audio_render (audio, (gint16 *) buffer->data + 2468, 1234, i - 1234); + } else +#endif + { + swfdec_audio_render (audio, (gint16 *) (void *) buffer->data, 0, i); + } + i = swfdec_audio_iterate (audio, i); + i = MIN (i, 4096); + swfdec_buffer_queue_push (queue, buffer); + } + depth = swfdec_buffer_queue_get_depth (queue); + if (depth == 0) { + swfdec_buffer_queue_unref (queue); + g_printerr ("Sprite contains no sound\n"); + return FALSE; + } + buffer = swfdec_buffer_queue_pull (queue, depth); + swfdec_buffer_queue_unref (queue); + wav = encode_wav (buffer, swfdec_audio_format_new (44100, 2, TRUE)); + swfdec_buffer_unref (buffer); + if (!g_file_set_contents (filename, (char *) wav->data, + wav->length, &error)) { + g_printerr ("Couldn't save sound to file \"%s\": %s\n", filename, error->message); + swfdec_buffer_unref (wav); + g_error_free (error); + return FALSE; + } + swfdec_buffer_unref (wav); + return TRUE; +} + +static cairo_surface_t * +surface_create_for_filename (const char *filename, int width, int height) +{ + guint len = strlen (filename); + cairo_surface_t *surface; + if (FALSE) { +#ifdef CAIRO_HAS_PDF_SURFACE + } else if (len >= 3 && g_ascii_strcasecmp (filename + len - 3, "pdf") == 0) { + surface = cairo_pdf_surface_create (filename, width, height); +#endif +#ifdef CAIRO_HAS_SVG_SURFACE + } else if (len >= 3 && g_ascii_strcasecmp (filename + len - 3, "svg") == 0) { + surface = cairo_svg_surface_create (filename, width, height); +#endif + } else { + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); + } + return surface; +} + +static gboolean +surface_destroy_for_type (cairo_surface_t *surface, const char *filename) +{ + if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_IMAGE) { + cairo_status_t status = cairo_surface_write_to_png (surface, filename); + if (status != CAIRO_STATUS_SUCCESS) { + g_printerr ("Error saving file: %s\n", cairo_status_to_string (status)); + cairo_surface_destroy (surface); + return FALSE; + } + } + cairo_surface_destroy (surface); + return TRUE; +} + +static gboolean +export_graphic (SwfdecGraphic *graphic, const char *filename) +{ + cairo_surface_t *surface; + cairo_t *cr; + guint width, height; + const SwfdecColorTransform trans = { 256, 0, 256, 0, 256, 0, 256, 0 }; + + if (SWFDEC_IS_SPRITE (graphic)) { + g_printerr ("Sprites can not be exported\n"); + return FALSE; + } + if (SWFDEC_IS_BUTTON (graphic)) { + g_printerr ("Buttons can not be exported\n"); + return FALSE; + } + width = ceil (graphic->extents.x1 / SWFDEC_TWIPS_SCALE_FACTOR) + - floor (graphic->extents.x0 / SWFDEC_TWIPS_SCALE_FACTOR); + height = ceil (graphic->extents.y1 / SWFDEC_TWIPS_SCALE_FACTOR) + - floor (graphic->extents.y0 / SWFDEC_TWIPS_SCALE_FACTOR); + surface = surface_create_for_filename (filename, width, height); + cr = cairo_create (surface); + cairo_translate (cr, - floor (graphic->extents.x0 / SWFDEC_TWIPS_SCALE_FACTOR), + - floor (graphic->extents.y0 / SWFDEC_TWIPS_SCALE_FACTOR)); + cairo_scale (cr, 1.0 / SWFDEC_TWIPS_SCALE_FACTOR, 1.0 / SWFDEC_TWIPS_SCALE_FACTOR); + swfdec_graphic_render (graphic, cr, &trans, &graphic->extents); + cairo_show_page (cr); + cairo_destroy (cr); + return surface_destroy_for_type (surface, filename); +} + +static gboolean +export_image (SwfdecImage *image, const char *filename) +{ + cairo_surface_t *surface = swfdec_image_create_surface (image); + + if (surface == NULL) + return FALSE; + return surface_destroy_for_type (surface, filename); +} + +static void +usage (const char *app) +{ + g_print ("usage: %s SWFFILE ID OUTFILE\n\n", app); +} + +int +main (int argc, char *argv[]) +{ + SwfdecCharacter *character; + int ret = 0; + SwfdecPlayer *player; + glong id; + + swfdec_init (); + + if (argc != 4) { + usage (argv[0]); + return 0; + } + + player = swfdec_player_new_from_file (argv[1]); + /* FIXME: HACK! */ + swfdec_player_advance (player, 0); + if (!SWFDEC_IS_SPRITE_MOVIE (player->priv->roots->data)) { + g_printerr ("Error parsing file \"%s\"\n", argv[1]); + g_object_unref (player); + player = NULL; + return 1; + } + id = strtol (argv[2], NULL, 0); + if (id >= 0) { + character = swfdec_swf_decoder_get_character ( + SWFDEC_SWF_DECODER (SWFDEC_MOVIE (player->priv->roots->data)->resource->decoder), + id); + } else { + character = SWFDEC_CHARACTER (SWFDEC_SWF_DECODER ( + SWFDEC_MOVIE (player->priv->roots->data)->resource->decoder)->main_sprite); + } + if (SWFDEC_IS_SPRITE (character)) { + if (!export_sprite_sound (SWFDEC_SPRITE (character), argv[3])) + ret = 1; + } else if (SWFDEC_IS_SOUND (character)) { + if (!export_sound (SWFDEC_SOUND (character), argv[3])) + ret = 1; + } else if (SWFDEC_IS_GRAPHIC (character)) { + if (!export_graphic (SWFDEC_GRAPHIC (character), argv[3])) + ret = 1; + } else if (SWFDEC_IS_IMAGE (character)) { + if (!export_image (SWFDEC_IMAGE (character), argv[3])) + ret = 1; + } else { + g_printerr ("id %ld does not specify an exportable object\n", id); + ret = 1; + } + + g_object_unref (player); + player = NULL; + + return ret; +} + diff --git a/tools/swfdec_out.c b/tools/swfdec_out.c new file mode 100644 index 0000000..ecf5a83 --- /dev/null +++ b/tools/swfdec_out.c @@ -0,0 +1,383 @@ +/* Swfdec + * Copyright (C) 2007 Benjamin Otte <otte at gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string.h> + +#include "swfdec_out.h" + +SwfdecOut * +swfdec_out_open (void) +{ + SwfdecOut *out = g_new0 (SwfdecOut, 1); + + out->data = g_malloc (SWFDEC_OUT_INITIAL); + out->ptr = out->data; + out->end = out->data + SWFDEC_OUT_INITIAL; + + return out; +} + +static void +swfdec_out_syncbits (SwfdecOut *out) +{ + g_return_if_fail (out != NULL); + + if (out->idx > 0) { + out->ptr++; + out->idx = 0; + } +} + +SwfdecBuffer * +swfdec_out_close (SwfdecOut *out) +{ + SwfdecBuffer *buffer; + + g_return_val_if_fail (out != NULL, NULL); + + swfdec_out_syncbits (out); + + buffer = swfdec_buffer_new (); + buffer->data = out->data; + buffer->length = out->ptr - out->data; + + g_free (out); + + return buffer; +} + +unsigned int +swfdec_out_get_bits (SwfdecOut *out) +{ + g_return_val_if_fail (out != NULL, 0); + + return (out->ptr - out->data) * 8 + out->idx; +} + +unsigned int +swfdec_out_left (SwfdecOut *out) +{ + g_return_val_if_fail (out != NULL, 0); + + return (out->end - out->ptr) * 8 - out->idx; +} + +void +swfdec_out_ensure_bits (SwfdecOut *out, unsigned int bits) +{ + unsigned int current, taken, needed; + + g_return_if_fail (out != NULL); + + current = swfdec_out_left (out); + if (current >= bits) + return; + taken = out->ptr - out->data; + needed = (bits - current + 7) / 8; + needed += SWFDEC_OUT_STEP; + needed -= needed % SWFDEC_OUT_STEP; + needed += out->end - out->data; + out->data = g_realloc (out->data, needed); + out->ptr = out->data + taken; + out->end = out->data + needed; +} + +void +swfdec_out_prepare_bytes (SwfdecOut *out, unsigned int bytes) +{ + g_return_if_fail (out != NULL); + + swfdec_out_syncbits (out); + swfdec_out_ensure_bits (out, bytes * 8); +} + +void +swfdec_out_put_data (SwfdecOut *out, const guint8 *data, guint length) +{ + g_return_if_fail (out != NULL); + + swfdec_out_prepare_bytes (out, length); + memcpy (out->ptr, data, length); + out->ptr += length; +} + +void +swfdec_out_put_buffer (SwfdecOut *out, SwfdecBuffer *buffer) +{ + g_return_if_fail (out != NULL); + + swfdec_out_prepare_bytes (out, buffer->length); + memcpy (out->ptr, buffer->data, buffer->length); + out->ptr += buffer->length; +} + +void +swfdec_out_put_u8 (SwfdecOut *out, guint i) +{ + g_return_if_fail (i <= G_MAXUINT8); + + swfdec_out_prepare_bytes (out, 1); + *out->ptr = i; + out->ptr++; +} + +void +swfdec_out_put_u16 (SwfdecOut *out, guint i) +{ + g_return_if_fail (i <= G_MAXUINT16); + + swfdec_out_prepare_bytes (out, 2); + *(guint16 *)out->ptr = GUINT16_TO_LE (i); + out->ptr += 2; +} + +void +swfdec_out_put_u32 (SwfdecOut *out, guint i) +{ + g_return_if_fail (i <= G_MAXUINT32); + + swfdec_out_prepare_bytes (out, 4); + *(guint32 *)out->ptr = GUINT32_TO_LE (i); + out->ptr += 4; +} + +void +swfdec_out_put_bit (SwfdecOut *out, gboolean bit) +{ + g_return_if_fail (out != NULL); + + swfdec_out_put_bits (out, bit ? 1 : 0, 1); +} + +void +swfdec_out_put_bits (SwfdecOut *out, guint bits, guint n_bits) +{ + g_return_if_fail (out != NULL); + + swfdec_out_ensure_bits (out, n_bits); + + /* FIXME: implement this less braindead */ + while (n_bits) { + guint bits_now = MIN (n_bits, 8 - out->idx); + guint value = bits >> (n_bits - bits_now); + + /* clear data if necessary */ + if (out->idx == 0) + *out->ptr = 0; + value &= (1 << bits_now) - 1; + value <<= 8 - out->idx - bits_now; + *out->ptr |= value; + out->idx += bits_now; + g_assert (out->idx <= 8); + if (out->idx == 8) { + out->ptr ++; + out->idx = 0; + } + n_bits -= bits_now; + } +} + +void +swfdec_out_put_sbits (SwfdecOut *out, int bits, guint n_bits) +{ + g_return_if_fail (out != NULL); + swfdec_out_put_bits (out, bits, n_bits); +} + +void +swfdec_out_put_string (SwfdecOut *out, const char *s) +{ + guint len; + + g_return_if_fail (out != NULL); + g_return_if_fail (s != NULL); + + len = strlen (s) + 1; + + swfdec_out_prepare_bytes (out, len); + memcpy (out->ptr, s, len); + out->ptr += len; +} + +static guint +swfdec_out_bits_required (guint x) +{ + guint ret = 0; + + while (x > 0) { + x >>= 1; + ret++; + } + return ret; +} + +static guint +swfdec_out_sbits_required (int x) +{ + if (x < 0) + x = !x; + return swfdec_out_bits_required (x) + 1; +} + +void +swfdec_out_put_rect (SwfdecOut *out, const SwfdecRect *rect) +{ + int x0, x1, y0, y1; + guint req, tmp; + + g_return_if_fail (out != NULL); + g_return_if_fail (rect != NULL); + + x0 = rect->x0; + y0 = rect->y0; + x1 = rect->x1; + y1 = rect->y1; + req = swfdec_out_sbits_required (x0); + tmp = swfdec_out_sbits_required (y0); + req = MAX (req, tmp); + tmp = swfdec_out_sbits_required (x1); + req = MAX (req, tmp); + tmp = swfdec_out_sbits_required (y1); + req = MAX (req, tmp); + swfdec_out_syncbits (out); + swfdec_out_put_bits (out, req, 5); + swfdec_out_put_sbits (out, x0, req); + swfdec_out_put_sbits (out, x1, req); + swfdec_out_put_sbits (out, y0, req); + swfdec_out_put_sbits (out, y1, req); + swfdec_out_syncbits (out); +} + +void +swfdec_out_put_matrix (SwfdecOut *out, const cairo_matrix_t *matrix) +{ + int x, y; + unsigned int xbits, ybits; + + if (matrix->xx != 1.0 || matrix->yy != 1.0) { + swfdec_out_put_bit (out, 1); + x = SWFDEC_DOUBLE_TO_FIXED (matrix->xx); + y = SWFDEC_DOUBLE_TO_FIXED (matrix->yy); + xbits = swfdec_out_sbits_required (x); + ybits = swfdec_out_sbits_required (y); + xbits = MAX (xbits, ybits); + swfdec_out_put_bits (out, xbits, 5); + swfdec_out_put_sbits (out, x, xbits); + swfdec_out_put_sbits (out, y, xbits); + } else { + swfdec_out_put_bit (out, 0); + } + if (matrix->xy != 0.0 || matrix->yx != 0.0) { + swfdec_out_put_bit (out, 1); + x = SWFDEC_DOUBLE_TO_FIXED (matrix->yx); + y = SWFDEC_DOUBLE_TO_FIXED (matrix->xy); + xbits = swfdec_out_sbits_required (x); + ybits = swfdec_out_sbits_required (y); + xbits = MAX (xbits, ybits); + swfdec_out_put_bits (out, xbits, 5); + swfdec_out_put_sbits (out, x, xbits); + swfdec_out_put_sbits (out, y, xbits); + } else { + swfdec_out_put_bit (out, 0); + } + x = matrix->x0; + y = matrix->y0; + xbits = swfdec_out_sbits_required (x); + ybits = swfdec_out_sbits_required (y); + xbits = MAX (xbits, ybits); + swfdec_out_put_bits (out, xbits, 5); + swfdec_out_put_sbits (out, x, xbits); + swfdec_out_put_sbits (out, y, xbits); + swfdec_out_syncbits (out); +} + +void +swfdec_out_put_color_transform (SwfdecOut *out, const SwfdecColorTransform *trans) +{ + gboolean has_add, has_mult; + unsigned int n_bits, tmp; + + has_mult = trans->ra != 256 || trans->ga != 256 || trans->ba != 256 || trans->aa != 256; + has_add = trans->rb != 0 || trans->gb != 0 || trans->bb != 0 || trans->ab != 0; + if (has_mult) { + n_bits = swfdec_out_sbits_required (trans->ra); + tmp = swfdec_out_sbits_required (trans->ga); + n_bits = MAX (tmp, n_bits); + tmp = swfdec_out_sbits_required (trans->ba); + n_bits = MAX (tmp, n_bits); + tmp = swfdec_out_sbits_required (trans->aa); + n_bits = MAX (tmp, n_bits); + } else { + n_bits = 0; + } + if (has_add) { + tmp = swfdec_out_sbits_required (trans->rb); + n_bits = MAX (tmp, n_bits); + tmp = swfdec_out_sbits_required (trans->gb); + n_bits = MAX (tmp, n_bits); + tmp = swfdec_out_sbits_required (trans->bb); + n_bits = MAX (tmp, n_bits); + tmp = swfdec_out_sbits_required (trans->ab); + n_bits = MAX (tmp, n_bits); + } + if (n_bits >= (1 << 4)) + n_bits = (1 << 4) - 1; + swfdec_out_put_bit (out, has_add); + swfdec_out_put_bit (out, has_mult); + swfdec_out_put_bits (out, n_bits, 4); + if (has_mult) { + swfdec_out_put_sbits (out, trans->ra, n_bits); + swfdec_out_put_sbits (out, trans->ga, n_bits); + swfdec_out_put_sbits (out, trans->ba, n_bits); + swfdec_out_put_sbits (out, trans->aa, n_bits); + } + if (has_add) { + swfdec_out_put_sbits (out, trans->rb, n_bits); + swfdec_out_put_sbits (out, trans->gb, n_bits); + swfdec_out_put_sbits (out, trans->bb, n_bits); + swfdec_out_put_sbits (out, trans->ab, n_bits); + } + swfdec_out_syncbits (out); +} + +void +swfdec_out_put_rgb (SwfdecOut *out, SwfdecColor color) +{ + g_return_if_fail (out != NULL); + + swfdec_out_put_u8 (out, SWFDEC_COLOR_R (color)); + swfdec_out_put_u8 (out, SWFDEC_COLOR_G (color)); + swfdec_out_put_u8 (out, SWFDEC_COLOR_B (color)); +} + +void +swfdec_out_put_rgba (SwfdecOut *out, SwfdecColor color) +{ + g_return_if_fail (out != NULL); + + swfdec_out_put_u8 (out, SWFDEC_COLOR_R (color)); + swfdec_out_put_u8 (out, SWFDEC_COLOR_G (color)); + swfdec_out_put_u8 (out, SWFDEC_COLOR_B (color)); + swfdec_out_put_u8 (out, SWFDEC_COLOR_A (color)); +} + diff --git a/tools/swfdec_out.h b/tools/swfdec_out.h new file mode 100644 index 0000000..e343f9d --- /dev/null +++ b/tools/swfdec_out.h @@ -0,0 +1,88 @@ +/* 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_OUT_H__ +#define __SWFDEC_OUT_H__ + +#include <libswfdec/swfdec_buffer.h> +#include <libswfdec/swfdec_color.h> +#include <libswfdec/swfdec_rect.h> + +G_BEGIN_DECLS + + +typedef struct _SwfdecOut SwfdecOut; + +struct _SwfdecOut { + unsigned char * data; + unsigned char * ptr; + unsigned int idx; + unsigned char * end; +}; + +#define SWFDEC_OUT_INITIAL (32) +#define SWFDEC_OUT_STEP (32) + +SwfdecOut * swfdec_out_open (void); +SwfdecBuffer * swfdec_out_close (SwfdecOut * out); + +unsigned int swfdec_out_get_bits (SwfdecOut * out); +unsigned int swfdec_out_left (SwfdecOut * out); +void swfdec_out_ensure_bits (SwfdecOut * out, + unsigned int bits); +void swfdec_out_prepare_bytes (SwfdecOut * out, + unsigned int bytes); + +void swfdec_out_put_bit (SwfdecOut * out, + gboolean bit); +void swfdec_out_put_bits (SwfdecOut * out, + guint bits, + guint n_bits); +void swfdec_out_put_sbits (SwfdecOut * out, + int bits, + guint n_bits); +void swfdec_out_put_data (SwfdecOut * out, + const guint8 * data, + guint length); +void swfdec_out_put_buffer (SwfdecOut * out, + SwfdecBuffer * buffer); +void swfdec_out_put_u8 (SwfdecOut * out, + guint i); +void swfdec_out_put_u16 (SwfdecOut * out, + guint i); +void swfdec_out_put_u32 (SwfdecOut * out, + guint i); +void swfdec_out_put_string (SwfdecOut * out, + const char * s); + +void swfdec_out_put_rgb (SwfdecOut * out, + SwfdecColor color); +void swfdec_out_put_rgba (SwfdecOut * out, + SwfdecColor color); +void swfdec_out_put_rect (SwfdecOut * out, + const SwfdecRect * rect); +void swfdec_out_put_matrix (SwfdecOut * out, + const cairo_matrix_t * matrix); +void swfdec_out_put_color_transform (SwfdecOut * out, + const SwfdecColorTransform *trans); + + +G_END_DECLS + +#endif diff --git a/tools/swfedit.c b/tools/swfedit.c new file mode 100644 index 0000000..24f2980 --- /dev/null +++ b/tools/swfedit.c @@ -0,0 +1,138 @@ +/* Swfedit + * 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 <gtk/gtk.h> +#include "swfedit_file.h" + +static void +save (GtkButton *button, SwfeditFile *file) +{ + GtkWidget *dialog; + GError *error = NULL; + + dialog = gtk_file_chooser_dialog_new ("Save file...", + GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (button))), + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, + GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, + NULL); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT); + gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE); + gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (dialog), file->filename); + if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { + g_free (file->filename); + file->filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + if (!swfedit_file_save (file, &error)) { + g_printerr ("Error saving file: %s\n", error->message); + g_error_free (error); + } + } + gtk_widget_destroy (dialog); +} + +static void +cell_renderer_edited (GtkCellRenderer *renderer, char *path, + char *new_text, SwfeditFile *file) +{ + GtkTreeIter iter; + + if (!gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (file), + &iter, path)) { + g_assert_not_reached (); + } + swfedit_token_set_iter (SWFEDIT_TOKEN (file), &iter, new_text); +} + +static gboolean +open_window (char *filename) +{ + SwfeditFile *file; + GtkWidget *window, *scroll, *box, *button, *treeview; + GError *error = NULL; + GtkTreeViewColumn *column; + GtkCellRenderer *renderer; + char *basename; + + file = swfedit_file_new (filename, &error); + if (file == NULL) { + g_printerr ("Error opening file %s: %s\n", filename, error->message); + g_error_free (error); + return FALSE; + } + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + basename = g_path_get_basename (filename); + if (basename) { + gtk_window_set_title (GTK_WINDOW (window), basename); + g_free (basename); + } + g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); + + box = gtk_vbox_new (FALSE, 3); + gtk_container_add (GTK_CONTAINER (window), box); + + scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_box_pack_start (GTK_BOX (box), scroll, TRUE, TRUE, 0); + + treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (file)); + gtk_container_add (GTK_CONTAINER (scroll), treeview); + + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes ("Name", renderer, + "text", SWFEDIT_COLUMN_NAME, "sensitive", SWFEDIT_COLUMN_VALUE_EDITABLE, NULL); + gtk_tree_view_column_set_resizable (column, TRUE); + gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); + + renderer = gtk_cell_renderer_text_new (); + g_object_set (G_OBJECT (renderer), "editable", TRUE, NULL); + g_signal_connect (renderer, "edited", G_CALLBACK (cell_renderer_edited), file); + column = gtk_tree_view_column_new_with_attributes ("Value", renderer, + "text", SWFEDIT_COLUMN_VALUE, "visible", SWFEDIT_COLUMN_VALUE_VISIBLE, + "sensitive", SWFEDIT_COLUMN_VALUE_EDITABLE, NULL); + gtk_tree_view_column_set_resizable (column, TRUE); + gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); + + button = gtk_button_new_from_stock (GTK_STOCK_SAVE); + g_signal_connect (button, "clicked", G_CALLBACK (save), file); + gtk_box_pack_start (GTK_BOX (box), button, FALSE, TRUE, 0); + + gtk_widget_show_all (window); + return TRUE; +} + +int +main (int argc, char **argv) +{ + gtk_init (&argc, &argv); + + if (argc <= 1) { + g_print ("Usage: %s FILENAME\n", argv[0]); + return 1; + } + if (open_window (argv[1])) { + gtk_main (); + return 0; + } else { + return 1; + } +} + diff --git a/tools/swfedit_file.c b/tools/swfedit_file.c new file mode 100644 index 0000000..e257010 --- /dev/null +++ b/tools/swfedit_file.c @@ -0,0 +1,297 @@ +/* Swfedit + * 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 <zlib.h> + +#include "libswfdec/swfdec_bits.h" +#include "libswfdec/swfdec_buffer.h" +#include "libswfdec/swfdec_debug.h" +#include "libswfdec/swfdec_swf_decoder.h" +#include "swfdec_out.h" +#include "swfedit_file.h" +#include "swfedit_tag.h" + +G_DEFINE_TYPE (SwfeditFile, swfedit_file, SWFEDIT_TYPE_TOKEN) + +static void +swfedit_file_dispose (GObject *object) +{ + SwfeditFile *file = SWFEDIT_FILE (object); + + g_free (file->filename); + + G_OBJECT_CLASS (swfedit_file_parent_class)->dispose (object); +} + +static void * +zalloc (void *opaque, unsigned int items, unsigned int size) +{ + return g_malloc (items * size); +} + +static void +zfree (void *opaque, void *addr) +{ + g_free (addr); +} + +static SwfdecBuffer * +swfenc_file_inflate (SwfdecBits *bits, guint size) +{ + SwfdecBuffer *decoded, *encoded; + z_stream z; + int ret; + + encoded = swfdec_bits_get_buffer (bits, -1); + if (encoded == NULL) + return NULL; + decoded = swfdec_buffer_new_and_alloc (size); + z.zalloc = zalloc; + z.zfree = zfree; + z.opaque = NULL; + z.next_in = encoded->data; + z.avail_in = encoded->length; + z.next_out = decoded->data; + z.avail_out = decoded->length; + ret = inflateInit (&z); + SWFDEC_DEBUG ("inflateInit returned %d", ret); + if (ret >= Z_OK) { + ret = inflate (&z, Z_SYNC_FLUSH); + SWFDEC_DEBUG ("inflate returned %d", ret); + } + inflateEnd (&z); + swfdec_buffer_unref (encoded); + if (ret < Z_OK) { + swfdec_buffer_unref (decoded); + return NULL; + } + return decoded; +} + +static SwfdecBuffer * +swf_parse_header1 (SwfeditFile *file, SwfdecBits *bits, GError **error) +{ + guint sig1, sig2, sig3, bytes_total; + + sig1 = swfdec_bits_get_u8 (bits); + sig2 = swfdec_bits_get_u8 (bits); + sig3 = swfdec_bits_get_u8 (bits); + if ((sig1 != 'F' && sig1 != 'C') || sig2 != 'W' || sig3 != 'S') { + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, + "This is not a SWF file"); + return NULL; + } + + swfedit_token_add (SWFEDIT_TOKEN (file), "version", SWFEDIT_TOKEN_UINT8, + GUINT_TO_POINTER (swfdec_bits_get_u8 (bits))); + bytes_total = swfdec_bits_get_u32 (bits) - 8; + + if (sig1 == 'C') { + /* compressed */ + SwfdecBuffer *ret = swfenc_file_inflate (bits, bytes_total); + if (ret == NULL) + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, + "Unable to uncompress file"); + return ret; + } else { + SwfdecBuffer *ret = swfdec_bits_get_buffer (bits, bytes_total); + if (ret == NULL) + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, + "File too small"); + return ret; + } +} + +static void +swf_parse_header2 (SwfeditFile *file, SwfdecBits *bits) +{ + swfedit_tag_read_token (SWFEDIT_TOKEN (file), bits, "rect", SWFEDIT_TOKEN_RECT, NULL); + swfedit_tag_read_token (SWFEDIT_TOKEN (file), bits, "rate", SWFEDIT_TOKEN_UINT16, NULL); + swfedit_tag_read_token (SWFEDIT_TOKEN (file), bits, "frames", SWFEDIT_TOKEN_UINT16, NULL); +} + +static gboolean +swfedit_file_parse (SwfeditFile *file, SwfdecBits *bits, GError **error) +{ + SwfdecBuffer *next; + + next = swf_parse_header1 (file, bits, error); + if (next == NULL) + return FALSE; + swfdec_bits_init (bits, next); + swf_parse_header2 (file, bits); + + while (swfdec_bits_left (bits)) { + guint x = swfdec_bits_get_u16 (bits); + G_GNUC_UNUSED guint tag = (x >> 6) & 0x3ff; + guint tag_len = x & 0x3f; + SwfdecBuffer *buffer; + SwfeditTag *item; + + if (tag_len == 0x3f) + tag_len = swfdec_bits_get_u32 (bits); + if (tag == 0) + break; + if (tag_len > 0) + buffer = swfdec_bits_get_buffer (bits, tag_len); + else + buffer = swfdec_buffer_new (); + if (buffer == NULL) { + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, + "Invalid contents in file"); + return FALSE; + } + item = swfedit_tag_new (SWFEDIT_TOKEN (file), tag, buffer); + swfedit_token_add (SWFEDIT_TOKEN (file), + swfdec_swf_decoder_get_tag_name (tag), + SWFEDIT_TOKEN_OBJECT, item); + } + swfdec_buffer_unref (next); + return TRUE; +} + +static void +swfedit_file_class_init (SwfeditFileClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->dispose = swfedit_file_dispose; +} + +static void +swfedit_file_init (SwfeditFile *s) +{ +} + +SwfeditFile * +swfedit_file_new (const char *filename, GError **error) +{ + SwfeditFile *file; + SwfdecBuffer *buffer; + SwfdecBits bits; + char *absolute; + + if (g_path_is_absolute (filename)) { + absolute = g_strdup (filename); + } else { + char *dir = g_get_current_dir (); + absolute = g_build_filename (dir, filename, NULL); + g_free (dir); + } + buffer = swfdec_buffer_new_from_file (filename, error); + if (buffer == NULL) + return NULL; + swfdec_bits_init (&bits, buffer); + file = g_object_new (SWFEDIT_TYPE_FILE, NULL); + file->filename = absolute; + if (!swfedit_file_parse (file, &bits, error)) { + swfdec_buffer_unref (buffer); + g_object_unref (file); + return NULL; + } + swfdec_buffer_unref (buffer); + return file; +} + +static SwfdecBuffer * +swfedit_file_write (SwfeditFile *file) +{ + guint i; + SwfeditToken *token = SWFEDIT_TOKEN (file); + SwfdecBufferQueue *queue; + SwfdecBuffer *buffer; + SwfdecOut *out; + + queue = swfdec_buffer_queue_new (); + /* write second part of header */ + out = swfdec_out_open (); + swfedit_tag_write_token (token, out, 1); + swfedit_tag_write_token (token, out, 2); + swfedit_tag_write_token (token, out, 3); + swfdec_buffer_queue_push (queue, swfdec_out_close (out)); + + for (i = 4; i < token->tokens->len; i++) { + SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, i); + g_assert (entry->type == SWFEDIT_TOKEN_OBJECT); + + buffer = swfedit_tag_write (entry->value); + out = swfdec_out_open (); + swfdec_out_put_u16 (out, SWFEDIT_TAG (entry->value)->tag << 6 | + MIN (buffer->length, 0x3f)); + if (buffer->length >= 0x3f) { + swfdec_out_put_u32 (out, buffer->length); + } + swfdec_buffer_queue_push (queue, swfdec_out_close (out)); + swfdec_buffer_queue_push (queue, buffer); + } + /* write closing tag */ + buffer = swfdec_buffer_new_and_alloc0 (2); + swfdec_buffer_queue_push (queue, buffer); + + /* FIXME: implement compression */ + out = swfdec_out_open (); + swfdec_out_put_u8 (out, 'F'); + swfdec_out_put_u8 (out, 'W'); + swfdec_out_put_u8 (out, 'S'); + swfedit_tag_write_token (token, out, 0); + swfdec_out_put_u32 (out, swfdec_buffer_queue_get_depth (queue) + 8); + swfdec_out_prepare_bytes (out, swfdec_buffer_queue_get_depth (queue)); + while ((buffer = swfdec_buffer_queue_pull_buffer (queue))) { + swfdec_out_put_buffer (out, buffer); + swfdec_buffer_unref (buffer); + } + swfdec_buffer_queue_unref (queue); + return swfdec_out_close (out); +} + +gboolean +swfedit_file_save (SwfeditFile *file, GError **error) +{ + SwfdecBuffer *buffer; + gboolean ret; + + g_return_val_if_fail (SWFEDIT_IS_FILE (file), FALSE); + + buffer = swfedit_file_write (file); + if (buffer == NULL) { + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, + "Failed to render file"); + return FALSE; + } + ret = g_file_set_contents (file->filename, (char *) buffer->data, + buffer->length, error); + swfdec_buffer_unref (buffer); + return ret; +} + +guint +swfedit_file_get_version (SwfeditFile *file) +{ + SwfeditTokenEntry *entry; + + g_return_val_if_fail (SWFEDIT_FILE (file), 3); + + entry = &g_array_index (SWFEDIT_TOKEN (file)->tokens, SwfeditTokenEntry, 0); + return GPOINTER_TO_UINT (entry->value); +} + diff --git a/tools/swfedit_file.h b/tools/swfedit_file.h new file mode 100644 index 0000000..ecd096a --- /dev/null +++ b/tools/swfedit_file.h @@ -0,0 +1,60 @@ +/* Swfedit + * 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 __SWFEDIT_FILE_H__ +#define __SWFEDIT_FILE_H__ + +#include <libswfdec/swfdec_rect.h> +#include "swfedit_token.h" + +G_BEGIN_DECLS + +typedef struct _SwfeditFile SwfeditFile; +typedef struct _SwfeditFileClass SwfeditFileClass; + +#define SWFEDIT_TYPE_FILE (swfedit_file_get_type()) +#define SWFEDIT_IS_FILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFEDIT_TYPE_FILE)) +#define SWFEDIT_IS_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFEDIT_TYPE_FILE)) +#define SWFEDIT_FILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFEDIT_TYPE_FILE, SwfeditFile)) +#define SWFEDIT_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFEDIT_TYPE_FILE, SwfeditFileClass)) +#define SWFEDIT_FILE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFEDIT_TYPE_FILE, SwfeditFileClass)) + +struct _SwfeditFile { + SwfeditToken token; + + char * filename; /* name this file is saved to */ +}; + +struct _SwfeditFileClass { + SwfeditTokenClass token_class; +}; + +GType swfedit_file_get_type (void); + +SwfeditFile * swfedit_file_new (const char * filename, + GError ** error); + +gboolean swfedit_file_save (SwfeditFile * file, + GError ** error); +guint swfedit_file_get_version (SwfeditFile * file); + + +G_END_DECLS + +#endif diff --git a/tools/swfedit_list.c b/tools/swfedit_list.c new file mode 100644 index 0000000..45e0dd5 --- /dev/null +++ b/tools/swfedit_list.c @@ -0,0 +1,149 @@ +/* Swfedit + * 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 "swfedit_list.h" + +G_DEFINE_TYPE (SwfeditList, swfedit_list, SWFEDIT_TYPE_TOKEN) + +static void +swfedit_list_dispose (GObject *object) +{ + //SwfeditList *list = SWFEDIT_LIST (object); + + G_OBJECT_CLASS (swfedit_list_parent_class)->dispose (object); +} + +static void +swfedit_list_changed (SwfeditToken *token, guint i) +{ + guint j; + SwfeditList *list = SWFEDIT_LIST (token); + SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, i); + + /* update visibility */ + for (j = i + 1; j % list->n_defs != 0; j++) { + if (list->def[j].n_items == (j % list->n_defs) + 1) { + swfedit_token_set_visible (token, j, entry->value != NULL); + } + } + /* update length */ + j = list->def[i % list->n_defs].n_items; + if (j != 0) { + entry = &g_array_index (token->tokens, + SwfeditTokenEntry, j - 1); + if (entry->type == SWFEDIT_TOKEN_UINT32) { + SwfdecOut *out = swfdec_out_open (); + SwfdecBuffer *buffer; + swfedit_tag_write_token (token, out, i); + buffer = swfdec_out_close (out); + if (entry->value != GUINT_TO_POINTER (buffer->length)) { + swfedit_token_set (token, i / list->n_defs * list->n_defs + j - 1, + GUINT_TO_POINTER (buffer->length)); + } + swfdec_buffer_unref (buffer); + } + } + /* maybe add items */ + if (i == token->tokens->len - 1) { + for (j = 0; j < list->n_defs; j++) { + const SwfeditTagDefinition *def = &list->def[(j + 1) % list->n_defs]; + swfedit_tag_add_token (SWFEDIT_TOKEN (list), def->name, def->type, def->hint); + } + } +} + +static void +swfedit_list_class_init (SwfeditListClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + SwfeditTokenClass *token_class = SWFEDIT_TOKEN_CLASS (klass); + + object_class->dispose = swfedit_list_dispose; + + token_class->changed = swfedit_list_changed; +} + +static void +swfedit_list_init (SwfeditList *list) +{ +} + +static SwfeditList * +swfedit_list_new_internal (const SwfeditTagDefinition *def) +{ + SwfeditList *list; + + list = g_object_new (SWFEDIT_TYPE_LIST, NULL); + list->def = def; + for (; def->name; def++) + list->n_defs++; + + return list; +} + +SwfeditList * +swfedit_list_new (const SwfeditTagDefinition *def) +{ + SwfeditList *list; + + g_return_val_if_fail (def != NULL, NULL); + + list = swfedit_list_new_internal (def); + swfedit_tag_add_token (SWFEDIT_TOKEN (list), def->name, def->type, def->hint); + + return list; +} + +SwfeditList * +swfedit_list_new_read (SwfeditToken *parent, SwfdecBits *bits, const SwfeditTagDefinition *def) +{ + SwfeditList *list; + SwfeditTokenEntry *entry; + guint offset; + + g_return_val_if_fail (bits != NULL, NULL); + g_return_val_if_fail (def != NULL, NULL); + + list = swfedit_list_new_internal (def); + SWFEDIT_TOKEN (list)->parent = parent; + offset = 0; + while (TRUE) { + def = list->def; + swfedit_tag_read_tag (SWFEDIT_TOKEN (list), bits, def); + entry = &g_array_index (SWFEDIT_TOKEN (list)->tokens, SwfeditTokenEntry, + SWFEDIT_TOKEN (list)->tokens->len - 1); + if (GPOINTER_TO_UINT (entry->value) == 0) + break; + + def++; + for (;def->name != NULL; def++) { + SwfeditTagDefinition def2 = *def; + if (def2.n_items) + def2.n_items += offset; + swfedit_tag_read_tag (SWFEDIT_TOKEN (list), bits, &def2); + } + offset += list->n_defs; + } + return list; +} + diff --git a/tools/swfedit_list.h b/tools/swfedit_list.h new file mode 100644 index 0000000..e0666f7 --- /dev/null +++ b/tools/swfedit_list.h @@ -0,0 +1,61 @@ +/* Swfedit + * 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 __SWFEDIT_LIST_H__ +#define __SWFEDIT_LIST_H__ + +#include "swfdec_out.h" +#include "swfedit_tag.h" + +G_BEGIN_DECLS + +typedef struct _SwfeditList SwfeditList; +typedef struct _SwfeditListClass SwfeditListClass; + +#define SWFEDIT_TYPE_LIST (swfedit_list_get_type()) +#define SWFEDIT_IS_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFEDIT_TYPE_LIST)) +#define SWFEDIT_IS_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFEDIT_TYPE_LIST)) +#define SWFEDIT_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFEDIT_TYPE_LIST, SwfeditList)) +#define SWFEDIT_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFEDIT_TYPE_LIST, SwfeditListClass)) +#define SWFEDIT_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFEDIT_TYPE_LIST, SwfeditListClass)) + +struct _SwfeditList { + SwfeditToken token; + + const SwfeditTagDefinition * def; /* definition of our items */ + guint n_defs; /* number of items in def */ +}; + +struct _SwfeditListClass { + SwfeditTokenClass token_class; +}; + +GType swfedit_list_get_type (void); + +SwfeditList * swfedit_list_new (const SwfeditTagDefinition * def); +SwfeditList * swfedit_list_new_read (SwfeditToken * parent, + SwfdecBits * bits, + const SwfeditTagDefinition * def); + +SwfdecBuffer * swfedit_list_write (SwfeditList * list); + + +G_END_DECLS + +#endif diff --git a/tools/swfedit_tag.c b/tools/swfedit_tag.c new file mode 100644 index 0000000..4a4bf67 --- /dev/null +++ b/tools/swfedit_tag.c @@ -0,0 +1,507 @@ +/* Swfedit + * 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 <stdlib.h> +#include <gtk/gtk.h> + +#include <libswfdec/swfdec_bits.h> +#include <libswfdec/swfdec_debug.h> +#include <libswfdec/swfdec_script_internal.h> +#include <libswfdec/swfdec_tag.h> +#include "swfedit_tag.h" +#include "swfdec_out.h" +#include "swfedit_file.h" +#include "swfedit_list.h" + +/*** LOAD/SAVE ***/ + +static void +swfedit_object_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) +{ + SwfdecBuffer *buffer; + + g_assert (SWFEDIT_IS_TOKEN (data)); + buffer = swfedit_tag_write (data); + swfdec_out_put_buffer (out, buffer); + swfdec_buffer_unref (buffer); +} + +static gpointer +swfedit_object_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) +{ + return swfedit_list_new_read (token, bits, hint); +} + +static void +swfedit_binary_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) +{ + swfdec_out_put_buffer (out, data); +} + +static gpointer +swfedit_binary_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) +{ + SwfdecBuffer *buffer = swfdec_bits_get_buffer (bits, -1); + if (buffer == NULL) + buffer = swfdec_buffer_new (); + return buffer; +} + +static void +swfedit_bit_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) +{ + swfdec_out_put_bit (out, data ? TRUE : FALSE); +} + +static gpointer +swfedit_bit_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) +{ + return GUINT_TO_POINTER (swfdec_bits_getbit (bits) ? 1 : 0); +} + +static void +swfedit_u8_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) +{ + swfdec_out_put_u8 (out, GPOINTER_TO_UINT (data)); +} + +static gpointer +swfedit_u8_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) +{ + return GUINT_TO_POINTER ((gulong) swfdec_bits_get_u8 (bits)); +} + +static void +swfedit_u16_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) +{ + swfdec_out_put_u16 (out, GPOINTER_TO_UINT (data)); +} + +static gpointer +swfedit_u16_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) +{ + return GUINT_TO_POINTER (swfdec_bits_get_u16 (bits)); +} + +static void +swfedit_u32_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) +{ + swfdec_out_put_u32 (out, GPOINTER_TO_UINT (data)); +} + +static gpointer +swfedit_u32_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) +{ + return GUINT_TO_POINTER (swfdec_bits_get_u32 (bits)); +} + +static void +swfedit_rect_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) +{ + swfdec_out_put_rect (out, data); +} + +static gpointer +swfedit_rect_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) +{ + SwfdecRect *rect = g_new (SwfdecRect, 1); + swfdec_bits_get_rect (bits, rect); + swfdec_bits_syncbits (bits); + return rect; +} + +static void +swfedit_string_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) +{ + swfdec_out_put_string (out, data); +} + +static gpointer +swfedit_string_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) +{ + char *s; + s = swfdec_bits_get_string (bits, 7); + if (s == NULL) + s = g_strdup (""); + return s; +} + +static void +swfedit_rgb_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) +{ + swfdec_out_put_rgb (out, GPOINTER_TO_UINT (data)); +} + +static gpointer +swfedit_rgb_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) +{ + return GUINT_TO_POINTER (swfdec_bits_get_color (bits)); +} + +static void +swfedit_rgba_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) +{ + swfdec_out_put_rgba (out, GPOINTER_TO_UINT (data)); +} + +static gpointer +swfedit_rgba_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) +{ + return GUINT_TO_POINTER (swfdec_bits_get_rgba (bits)); +} + +static void +swfedit_matrix_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) +{ + swfdec_out_put_matrix (out, data); +} + +static gpointer +swfedit_matrix_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) +{ + cairo_matrix_t *matrix = g_new (cairo_matrix_t, 1); + + swfdec_bits_get_matrix (bits, matrix, NULL); + swfdec_bits_syncbits (bits); + return matrix; +} + +static void +swfedit_ctrans_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) +{ + swfdec_out_put_color_transform (out, data); +} + +static gpointer +swfedit_ctrans_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) +{ + SwfdecColorTransform *ctrans = g_new (SwfdecColorTransform, 1); + + swfdec_bits_get_color_transform (bits, ctrans); + swfdec_bits_syncbits (bits); + return ctrans; +} + +static void +swfedit_script_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) +{ + SwfdecScript *script = data; + + swfdec_out_put_buffer (out, script->buffer); +} + +static gpointer +swfedit_script_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) +{ + while (token->parent) + token = token->parent; + if (!SWFEDIT_IS_FILE (token)) + return NULL; + return swfdec_script_new_from_bits (bits, "original script", swfedit_file_get_version (SWFEDIT_FILE (token))); +} + +static void +swfedit_clipeventflags_write (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint) +{ + while (token->parent) + token = token->parent; + g_assert (SWFEDIT_IS_FILE (token)); + if (swfedit_file_get_version (SWFEDIT_FILE (token)) >= 6) + swfdec_out_put_u32 (out, GPOINTER_TO_UINT (data)); + else + swfdec_out_put_u16 (out, GPOINTER_TO_UINT (data)); +} + +static gpointer +swfedit_clipeventflags_read (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint) +{ + while (token->parent) + token = token->parent; + g_assert (SWFEDIT_IS_FILE (token)); + if (swfedit_file_get_version (SWFEDIT_FILE (token)) >= 6) + return GUINT_TO_POINTER (swfdec_bits_get_u32 (bits)); + else + return GUINT_TO_POINTER (swfdec_bits_get_u16 (bits)); +} + +struct { + void (* write) (SwfeditToken *token, gpointer data, SwfdecOut *out, gconstpointer hint); + gpointer (* read) (SwfeditToken *token, SwfdecBits *bits, gconstpointer hint); +} operations[SWFEDIT_N_TOKENS] = { + { swfedit_object_write, swfedit_object_read }, + { swfedit_binary_write, swfedit_binary_read }, + { swfedit_bit_write, swfedit_bit_read }, + { swfedit_u8_write, swfedit_u8_read }, + { swfedit_u16_write, swfedit_u16_read }, + { swfedit_u32_write, swfedit_u32_read }, + { swfedit_string_write, swfedit_string_read }, + { swfedit_rect_write, swfedit_rect_read }, + { swfedit_rgb_write, swfedit_rgb_read }, + { swfedit_rgba_write, swfedit_rgba_read }, + { swfedit_matrix_write, swfedit_matrix_read }, + { swfedit_ctrans_write, swfedit_ctrans_read }, + { swfedit_script_write, swfedit_script_read }, + { swfedit_clipeventflags_write, swfedit_clipeventflags_read }, +}; + +void +swfedit_tag_write_token (SwfeditToken *token, SwfdecOut *out, guint i) +{ + SwfeditTokenEntry *entry; + + g_return_if_fail (SWFEDIT_IS_TOKEN (token)); + g_return_if_fail (i < token->tokens->len); + + entry = &g_array_index (token->tokens, + SwfeditTokenEntry, i); + g_assert (operations[entry->type].write != NULL); + operations[entry->type].write (token, entry->value, out, NULL); +} + +SwfdecBuffer * +swfedit_tag_write (SwfeditToken *token) +{ + guint i; + SwfdecOut *out; + + g_return_val_if_fail (SWFEDIT_IS_TOKEN (token), NULL); + + out = swfdec_out_open (); + for (i = 0; i < token->tokens->len; i++) { + SwfeditTokenEntry *entry = &g_array_index (token->tokens, + SwfeditTokenEntry, i); + if (entry->visible) + swfedit_tag_write_token (token, out, i); + } + return swfdec_out_close (out); +} + +void +swfedit_tag_read_token (SwfeditToken *token, SwfdecBits *bits, + const char *name, SwfeditTokenType type, gconstpointer hint) +{ + gpointer data; + + g_return_if_fail (SWFEDIT_IS_TOKEN (token)); + g_return_if_fail (name != NULL); + + g_assert (operations[type].read != NULL); + data = operations[type].read (token, bits, hint); + swfedit_token_add (token, name, type, data); +} + +/*** TAGS ***/ + +static const SwfeditTagDefinition ShowFrame[] = { { NULL, 0, 0, NULL } }; +static const SwfeditTagDefinition SetBackgroundColor[] = { { "color", SWFEDIT_TOKEN_RGB, 0, NULL }, { NULL, 0, 0, NULL } }; +static const SwfeditTagDefinition PlaceObject2Action[] = { + { "flags", SWFEDIT_TOKEN_CLIPEVENTFLAGS, 0, NULL }, + { "size", SWFEDIT_TOKEN_UINT32, 0, NULL }, + //{ "key code", SWFEDIT_TOKEN_UINT8, 0, NULL }, /* only if flag foo is set */ + { "script", SWFEDIT_TOKEN_SCRIPT, 2, NULL }, + { NULL, 0, 0, NULL } +}; +static const SwfeditTagDefinition PlaceObject2[] = { + { "has clip actions", SWFEDIT_TOKEN_BIT, 0, NULL }, + { "has clip depth", SWFEDIT_TOKEN_BIT, 0, NULL }, + { "has name", SWFEDIT_TOKEN_BIT, 0, NULL }, + { "has ratio", SWFEDIT_TOKEN_BIT, 0, NULL }, + { "has color transform", SWFEDIT_TOKEN_BIT, 0, NULL }, + { "has matrix", SWFEDIT_TOKEN_BIT, 0, NULL }, + { "has character", SWFEDIT_TOKEN_BIT, 0, NULL }, + { "move", SWFEDIT_TOKEN_BIT, 0, NULL }, + { "depth", SWFEDIT_TOKEN_UINT16, 0, NULL }, + { "character", SWFEDIT_TOKEN_UINT16, 7, NULL }, + { "matrix", SWFEDIT_TOKEN_MATRIX, 6, NULL }, + { "color transform", SWFEDIT_TOKEN_CTRANS, 5, NULL }, + { "ratio", SWFEDIT_TOKEN_UINT16, 4, NULL }, + { "name", SWFEDIT_TOKEN_STRING, 3, NULL }, + { "clip depth", SWFEDIT_TOKEN_UINT16, 2, NULL }, + { "reserved", SWFEDIT_TOKEN_UINT16, 1, NULL }, + { "all flags", SWFEDIT_TOKEN_CLIPEVENTFLAGS, 1, NULL }, + { "actions", SWFEDIT_TOKEN_OBJECT, 1, PlaceObject2Action }, + { NULL, 0, 0, NULL } +}; +static const SwfeditTagDefinition DoAction[] = { + { "action", SWFEDIT_TOKEN_SCRIPT, 0, NULL }, + { NULL, 0, 0, NULL } +}; +static const SwfeditTagDefinition DoInitAction[] = { + { "character", SWFEDIT_TOKEN_UINT16, 0, NULL }, + { "action", SWFEDIT_TOKEN_SCRIPT, 0, NULL }, + { NULL, 0, 0, NULL } +}; + +static const SwfeditTagDefinition *tags[] = { + [SWFDEC_TAG_SHOWFRAME] = ShowFrame, + [SWFDEC_TAG_SETBACKGROUNDCOLOR] = SetBackgroundColor, + [SWFDEC_TAG_PLACEOBJECT2] = PlaceObject2, + [SWFDEC_TAG_DOACTION] = DoAction, + [SWFDEC_TAG_DOINITACTION] = DoInitAction, +}; + +static const SwfeditTagDefinition * +swfedit_tag_get_definition (guint tag) +{ + if (tag >= G_N_ELEMENTS (tags)) + return NULL; + return tags[tag]; +} + +/*** SWFEDIT_TAG ***/ + +G_DEFINE_TYPE (SwfeditTag, swfedit_tag, SWFEDIT_TYPE_TOKEN) + +static void +swfedit_tag_dispose (GObject *object) +{ + //SwfeditTag *tag = SWFEDIT_TAG (object); + + G_OBJECT_CLASS (swfedit_tag_parent_class)->dispose (object); +} + +static void +swfedit_tag_changed (SwfeditToken *token, guint i) +{ + guint j; + SwfeditTag *tag = SWFEDIT_TAG (token); + SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, i); + const SwfeditTagDefinition *def = swfedit_tag_get_definition (tag->tag); + + if (def == NULL) + return; + + for (j = i + 1; def[j].name; j++) { + if (def[j].n_items == i + 1) { + swfedit_token_set_visible (token, j, entry->value != NULL); + } + } + if (def[i].n_items != 0) { + entry = &g_array_index (token->tokens, + SwfeditTokenEntry, def[i].n_items - 1); + if (entry->type == SWFEDIT_TOKEN_UINT32) { + SwfdecOut *out = swfdec_out_open (); + SwfdecBuffer *buffer; + swfedit_tag_write_token (token, out, def[i].n_items - 1); + buffer = swfdec_out_close (out); + if (entry->value != GUINT_TO_POINTER (buffer->length)) { + swfedit_token_set (token, def[i].n_items - 1, + GUINT_TO_POINTER (buffer->length)); + } + swfdec_buffer_unref (buffer); + } + } +} + +static void +swfedit_tag_class_init (SwfeditTagClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + SwfeditTokenClass *token_class = SWFEDIT_TOKEN_CLASS (klass); + + object_class->dispose = swfedit_tag_dispose; + + token_class->changed = swfedit_tag_changed; +} + +static void +swfedit_tag_init (SwfeditTag *tag) +{ +} + +void +swfedit_tag_add_token (SwfeditToken *token, const char *name, SwfeditTokenType type, + gconstpointer hint) +{ + gpointer data; + + if (type == SWFEDIT_TOKEN_OBJECT) { + data = swfedit_list_new (hint); + SWFEDIT_TOKEN (data)->parent = token; + } else { + data = swfedit_token_new_token (type); + } + swfedit_token_add (token, name, type, data); +} + +void +swfedit_tag_read_tag (SwfeditToken *token, SwfdecBits *bits, + const SwfeditTagDefinition *def) +{ + g_return_if_fail (SWFEDIT_IS_TOKEN (token)); + g_return_if_fail (bits != NULL); + g_return_if_fail (def != NULL); + + if (def->n_items != 0) { + SwfeditTokenEntry *entry = &g_array_index (token->tokens, + SwfeditTokenEntry, def->n_items - 1); + if (GPOINTER_TO_UINT (entry->value) == 0) { + swfedit_tag_add_token (token, def->name, def->type, def->hint); + swfedit_token_set_visible (token, token->tokens->len - 1, FALSE); + } else if (entry->type == SWFEDIT_TOKEN_BIT) { + swfedit_tag_read_token (token, bits, def->name, def->type, def->hint); + } else { + guint length = GPOINTER_TO_UINT (entry->value); + SwfdecBuffer *buffer = swfdec_bits_get_buffer (bits, length); + if (buffer == NULL) { + swfedit_tag_add_token (token, def->name, def->type, def->hint); + } else { + SwfdecBits bits2; + swfdec_bits_init (&bits2, buffer); + swfedit_tag_read_token (token, &bits2, def->name, def->type, def->hint); + swfdec_buffer_unref (buffer); + } + } + } else { + swfedit_tag_read_token (token, bits, def->name, def->type, def->hint); + } +} + +SwfeditTag * +swfedit_tag_new (SwfeditToken *parent, guint tag, SwfdecBuffer *buffer) +{ + SwfeditTag *item; + const SwfeditTagDefinition *def; + + g_return_val_if_fail (SWFEDIT_IS_TOKEN (parent), NULL); + + item = g_object_new (SWFEDIT_TYPE_TAG, NULL); + item->tag = tag; + SWFEDIT_TOKEN (item)->parent = parent; + def = swfedit_tag_get_definition (tag); + if (def) { + SwfdecBits bits; + swfdec_bits_init (&bits, buffer); + for (;def->name != NULL; def++) { + swfedit_tag_read_tag (SWFEDIT_TOKEN (item), &bits, def); + } + if (swfdec_bits_left (&bits)) { + SWFDEC_WARNING ("%u bytes %u bits left unparsed", + swfdec_bits_left (&bits) / 8, swfdec_bits_left (&bits) % 8); + } + } else { + swfedit_token_add (SWFEDIT_TOKEN (item), "contents", SWFEDIT_TOKEN_BINARY, buffer); + } + return item; +} + diff --git a/tools/swfedit_tag.h b/tools/swfedit_tag.h new file mode 100644 index 0000000..2f1d231 --- /dev/null +++ b/tools/swfedit_tag.h @@ -0,0 +1,83 @@ +/* Swfedit + * 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 __SWFEDIT_TAG_H__ +#define __SWFEDIT_TAG_H__ + +#include <libswfdec/swfdec_buffer.h> +#include <libswfdec/swfdec_bits.h> +#include "swfdec_out.h" +#include "swfedit_token.h" + +G_BEGIN_DECLS + +typedef struct _SwfeditTag SwfeditTag; +typedef struct _SwfeditTagClass SwfeditTagClass; +typedef struct _SwfeditTagDefinition SwfeditTagDefinition; + +struct _SwfeditTagDefinition { + const char * name; /* name to use for this field */ + SwfeditTokenType type; /* type of this field */ + guint n_items; /* 1-indexed field to look at for item count (or 0 to use 1 item) */ + gconstpointer hint; /* hint to pass to field when creating */ +}; + +#define SWFEDIT_TYPE_TAG (swfedit_tag_get_type()) +#define SWFEDIT_IS_TAG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFEDIT_TYPE_TAG)) +#define SWFEDIT_IS_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFEDIT_TYPE_TAG)) +#define SWFEDIT_TAG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFEDIT_TYPE_TAG, SwfeditTag)) +#define SWFEDIT_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFEDIT_TYPE_TAG, SwfeditTagClass)) +#define SWFEDIT_TAG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFEDIT_TYPE_TAG, SwfeditTagClass)) + +struct _SwfeditTag { + SwfeditToken token; + + guint tag; /* tag type */ +}; + +struct _SwfeditTagClass { + SwfeditTokenClass token_class; +}; + +GType swfedit_tag_get_type (void); + +SwfeditTag * swfedit_tag_new (SwfeditToken * parent, + guint tag, + SwfdecBuffer * buffer); + +SwfdecBuffer * swfedit_tag_write (SwfeditToken * token); +void swfedit_tag_write_token (SwfeditToken * token, + SwfdecOut * out, + guint i); +void swfedit_tag_add_token (SwfeditToken * token, + const char * name, + SwfeditTokenType type, + gconstpointer hint); +void swfedit_tag_read_token (SwfeditToken * token, + SwfdecBits * bits, + const char * name, + SwfeditTokenType type, + gconstpointer hint); +void swfedit_tag_read_tag (SwfeditToken * token, + SwfdecBits * bits, + const SwfeditTagDefinition *def); + +G_END_DECLS + +#endif diff --git a/tools/swfedit_token.c b/tools/swfedit_token.c new file mode 100644 index 0000000..34496df --- /dev/null +++ b/tools/swfedit_token.c @@ -0,0 +1,797 @@ +/* Swfedit + * 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, to_string 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 <stdlib.h> +#include <string.h> +#include <gtk/gtk.h> +#include <libswfdec/swfdec_buffer.h> +#include <libswfdec/swfdec_color.h> +#include <libswfdec/swfdec_script_internal.h> +#include "swfedit_token.h" + +/*** CONVERTERS ***/ + +static gboolean +swfedit_parse_hex (const char *s, guint *result) +{ + guint byte; + + if (s[0] >= '0' && s[0] <= '9') + byte = s[0] - '0'; + else if (s[0] >= 'a' && s[0] <= 'f') + byte = s[0] + 10 - 'a'; + else if (s[0] >= 'A' && s[0] <= 'F') + byte = s[0] + 10 - 'A'; + else + return FALSE; + s++; + byte *= 16; + if (s[0] >= '0' && s[0] <= '9') + byte += s[0] - '0'; + else if (s[0] >= 'a' && s[0] <= 'f') + byte += s[0] + 10 - 'a'; + else if (s[0] >= 'A' && s[0] <= 'F') + byte += s[0] + 10 - 'A'; + else + return FALSE; + *result = byte; + return TRUE; +} + +static gpointer +swfedit_binary_new (void) +{ + return swfdec_buffer_new (); +} + +static gboolean +swfedit_binary_from_string (const char *s, gpointer* result) +{ + GByteArray *array = g_byte_array_new (); + guint byte; + guint8 add; + + while (g_ascii_isspace (*s)) s++; + do { + if (!swfedit_parse_hex (s, &byte)) + break; + s += 2; + add = byte; + g_byte_array_append (array, &add, 1); + while (g_ascii_isspace (*s)) s++; + } while (*s != '\0'); + if (*s == '\0') { + SwfdecBuffer *buffer = swfdec_buffer_new (); + buffer->length = array->len; + buffer->data = array->data; + g_byte_array_free (array, FALSE); + *result = buffer; + return TRUE; + } + g_byte_array_free (array, TRUE); + return FALSE; +} + +static char * +swfedit_binary_to_string (gconstpointer value) +{ + guint i; + const SwfdecBuffer *buffer = value; + GString *string = g_string_new (""); + + for (i = 0; i < buffer->length; i++) { + if (i && i % 4 == 0) + g_string_append_c (string, ' '); + g_string_append_printf (string, "%02X", buffer->data[i]); + } + return g_string_free (string, FALSE); +} + +static gboolean +swfedit_bit_from_string (const char *s, gpointer* result) +{ + if (s[0] == '1' && s[1] == '\0') + *result = GUINT_TO_POINTER (1); + else if (s[0] == '0' && s[1] == '\0') + *result = GUINT_TO_POINTER (0); + else + return FALSE; + return TRUE; +} + +static char * +swfedit_bit_to_string (gconstpointer value) +{ + return g_strdup (value ? "1" : "0"); +} + +static gboolean +swfedit_from_string_unsigned (const char *s, gulong max, gpointer* result) +{ + char *end; + gulong u; + + g_assert (max <= G_MAXUINT); + u = strtoul (s, &end, 10); + if (*end != '\0') + return FALSE; + if (u > max) + return FALSE; + *result = GUINT_TO_POINTER (u); + return TRUE; +} + +static gboolean +swfedit_uint8_from_string (const char *s, gpointer* result) +{ + return swfedit_from_string_unsigned (s, G_MAXUINT8, result); +} + +static gboolean +swfedit_uint16_from_string (const char *s, gpointer* result) +{ + return swfedit_from_string_unsigned (s, G_MAXUINT16, result); +} + +static gboolean +swfedit_uint32_from_string (const char *s, gpointer* result) +{ + return swfedit_from_string_unsigned (s, G_MAXUINT32, result); +} + +static char * +swfedit_to_string_unsigned (gconstpointer value) +{ + return g_strdup_printf ("%u", GPOINTER_TO_UINT (value)); +} + +static char * +swfedit_string_to_string (gconstpointer value) +{ + return g_strdup (value); +} + +static gboolean +swfedit_string_from_string (const char *s, gpointer* result) +{ + *result = g_strdup (s); + return TRUE; +} + +static gpointer +swfedit_rect_new (void) +{ + return g_new0 (SwfdecRect, 1); +} + +static gboolean +swfedit_rect_from_string (const char *s, gpointer* result) +{ + return FALSE; +} + +static char * +swfedit_rect_to_string (gconstpointer value) +{ + const SwfdecRect *rect = value; + + return g_strdup_printf ("%d, %d, %d, %d", (int) rect->x0, (int) rect->y0, + (int) rect->x1, (int) rect->y1); +} + +static gboolean +swfedit_rgb_from_string (const char *s, gpointer* result) +{ + guint r, g, b; + if (strlen (s) != 6) + return FALSE; + if (!swfedit_parse_hex (s, &r)) + return FALSE; + s += 2; + if (!swfedit_parse_hex (s, &g)) + return FALSE; + s += 2; + if (!swfedit_parse_hex (s, &b)) + return FALSE; + *result = GUINT_TO_POINTER (SWFDEC_COLOR_COMBINE (r, g, b, 0xFF)); + return TRUE; +} + +static char * +swfedit_rgb_to_string (gconstpointer value) +{ + guint c = GPOINTER_TO_UINT (value); + + return g_strdup_printf ("%02X%02X%02X", SWFDEC_COLOR_R (c), + SWFDEC_COLOR_G (c), SWFDEC_COLOR_B (c)); +} + +static gboolean +swfedit_rgba_from_string (const char *s, gpointer* result) +{ + guint r, g, b, a; + if (strlen (s) != 8) + return FALSE; + if (!swfedit_parse_hex (s, &a)) + return FALSE; + s += 2; + if (!swfedit_parse_hex (s, &r)) + return FALSE; + s += 2; + if (!swfedit_parse_hex (s, &g)) + return FALSE; + s += 2; + if (!swfedit_parse_hex (s, &b)) + return FALSE; + *result = GUINT_TO_POINTER (SWFDEC_COLOR_COMBINE (r, g, b, a)); + return TRUE; +} + +static char * +swfedit_rgba_to_string (gconstpointer value) +{ + guint c = GPOINTER_TO_UINT (value); + + return g_strdup_printf ("%02X%02X%02X%02X", SWFDEC_COLOR_R (c), + SWFDEC_COLOR_G (c), SWFDEC_COLOR_B (c), SWFDEC_COLOR_A (c)); +} + +static gpointer +swfedit_matrix_new (void) +{ + cairo_matrix_t *matrix = g_new (cairo_matrix_t, 1); + + cairo_matrix_init_identity (matrix); + return matrix; +} + +static gboolean +swfedit_matrix_from_string (const char *s, gpointer* result) +{ + return FALSE; +} + +static char * +swfedit_matrix_to_string (gconstpointer value) +{ + const cairo_matrix_t *mat = value; + + return g_strdup_printf ("{%g %g, %g %g} + {%g, %g}", + mat->xx, mat->xy, mat->yx, mat->yy, mat->x0, mat->y0); +} + +static gpointer +swfedit_ctrans_new (void) +{ + SwfdecColorTransform *trans = g_new (SwfdecColorTransform, 1); + + swfdec_color_transform_init_identity (trans); + return trans; +} + +static gboolean +swfedit_ctrans_from_string (const char *s, gpointer* result) +{ + return FALSE; +} + +static char * +swfedit_ctrans_to_string (gconstpointer value) +{ + const SwfdecColorTransform *trans = value; + + return g_strdup_printf ("{%d %d} {%d %d} {%d %d} {%d %d}", + trans->ra, trans->rb, trans->ga, trans->gb, + trans->ba, trans->bb, trans->aa, trans->ab); +} + +static gpointer +swfedit_script_new (void) +{ + return NULL; +} + +static gboolean +swfedit_script_from_string (const char *s, gpointer* result) +{ + gpointer buffer; + SwfdecScript *script; + + if (!swfedit_binary_from_string (s, &buffer)) { + return FALSE; + } + + script = swfdec_script_new (buffer, "unknown", 6 /* FIXME */); + if (script != NULL) { + *result = script; + return TRUE; + } else { + return FALSE; + } +} + +static char * +swfedit_script_to_string (gconstpointer value) +{ + if (value == NULL) + return g_strdup (""); + else + return swfedit_binary_to_string (((SwfdecScript *) value)->buffer); +} + +static void +swfedit_script_free (gpointer script) +{ + if (script) + swfdec_script_unref (script); +} + +struct { + gpointer (* new) (void); + gboolean (* from_string) (const char *s, gpointer *); + char * (* to_string) (gconstpointer value); + void (* free) (gpointer value); +} converters[SWFEDIT_N_TOKENS] = { + { NULL, NULL, NULL, g_object_unref }, + { swfedit_binary_new, swfedit_binary_from_string, swfedit_binary_to_string, (GDestroyNotify) swfdec_buffer_unref }, + { NULL, swfedit_bit_from_string, swfedit_bit_to_string, NULL }, + { NULL, swfedit_uint8_from_string, swfedit_to_string_unsigned, NULL }, + { NULL, swfedit_uint16_from_string, swfedit_to_string_unsigned, NULL }, + { NULL, swfedit_uint32_from_string, swfedit_to_string_unsigned, NULL }, + { NULL, swfedit_string_from_string, swfedit_string_to_string, g_free }, + { swfedit_rect_new, swfedit_rect_from_string, swfedit_rect_to_string, g_free }, + { NULL, swfedit_rgb_from_string, swfedit_rgb_to_string, NULL }, + { NULL, swfedit_rgba_from_string, swfedit_rgba_to_string, NULL }, + { swfedit_matrix_new, swfedit_matrix_from_string, swfedit_matrix_to_string, g_free }, + { swfedit_ctrans_new, swfedit_ctrans_from_string, swfedit_ctrans_to_string, g_free }, + { swfedit_script_new, swfedit_script_from_string, swfedit_script_to_string, swfedit_script_free }, + { NULL, swfedit_uint32_from_string, swfedit_to_string_unsigned, NULL }, +}; + +gpointer +swfedit_token_new_token (SwfeditTokenType type) +{ + gpointer ret; + + g_assert (type < G_N_ELEMENTS (converters)); + + if (!converters[type].new) + return NULL; + ret = converters[type].new (); + return ret; +} + +/*** GTK_TREE_MODEL ***/ + +#if 0 +# define REPORT g_print ("%s\n", G_STRFUNC) +#else +# define REPORT +#endif +static GtkTreeModelFlags +swfedit_token_get_flags (GtkTreeModel *tree_model) +{ + REPORT; + return 0; +} + +static gint +swfedit_token_get_n_columns (GtkTreeModel *tree_model) +{ + SwfeditToken *token = SWFEDIT_TOKEN (tree_model); + + REPORT; + return token->tokens->len; +} + +static GType +swfedit_token_get_column_type (GtkTreeModel *tree_model, gint index_) +{ + REPORT; + switch (index_) { + case SWFEDIT_COLUMN_NAME: + return G_TYPE_STRING; + case SWFEDIT_COLUMN_VALUE_VISIBLE: + return G_TYPE_BOOLEAN; + case SWFEDIT_COLUMN_VALUE_EDITABLE: + return G_TYPE_BOOLEAN; + case SWFEDIT_COLUMN_VALUE: + return G_TYPE_STRING; + default: + break; + } + g_assert_not_reached (); + return G_TYPE_NONE; +} + +static gboolean +swfedit_token_get_iter (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path) +{ + SwfeditToken *token = SWFEDIT_TOKEN (tree_model); + guint i = gtk_tree_path_get_indices (path)[0]; + SwfeditTokenEntry *entry; + + REPORT; + if (i > token->tokens->len) + return FALSE; + entry = &g_array_index (token->tokens, SwfeditTokenEntry, i); + if (gtk_tree_path_get_depth (path) > 1) { + GtkTreePath *new; + int j; + int *indices; + gboolean ret; + + if (entry->type != SWFEDIT_TOKEN_OBJECT) + return FALSE; + new = gtk_tree_path_new (); + indices = gtk_tree_path_get_indices (path); + for (j = 1; j < gtk_tree_path_get_depth (path); j++) { + gtk_tree_path_append_index (new, indices[j]); + } + ret = swfedit_token_get_iter (GTK_TREE_MODEL (entry->value), iter, new); + gtk_tree_path_free (new); + return ret; + } else { + iter->stamp = 0; /* FIXME */ + iter->user_data = token; + iter->user_data2 = GINT_TO_POINTER (i); + return TRUE; + } +} + +static GtkTreePath * +swfedit_token_get_path (GtkTreeModel *tree_model, GtkTreeIter *iter) +{ + SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data); + GtkTreePath *path = gtk_tree_path_new_from_indices (GPOINTER_TO_INT (iter->user_data2), -1); + + REPORT; + while (token->parent) { + guint i; + SwfeditToken *parent = token->parent; + for (i = 0; i < parent->tokens->len; i++) { + SwfeditTokenEntry *entry = &g_array_index (parent->tokens, SwfeditTokenEntry, i); + if (entry->type != SWFEDIT_TOKEN_OBJECT) + continue; + if (entry->value == token) + break; + } + gtk_tree_path_prepend_index (path, i); + token = parent; + } + return path; +} + +static void +swfedit_token_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter, + gint column, GValue *value) +{ + SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data); + SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, GPOINTER_TO_INT (iter->user_data2)); + + REPORT; + switch (column) { + case SWFEDIT_COLUMN_NAME: + g_value_init (value, G_TYPE_STRING); + g_value_set_string (value, entry->name); + return; + case SWFEDIT_COLUMN_VALUE_VISIBLE: + g_value_init (value, G_TYPE_BOOLEAN); + g_value_set_boolean (value, converters[entry->type].to_string != NULL); + return; + case SWFEDIT_COLUMN_VALUE_EDITABLE: + g_value_init (value, G_TYPE_BOOLEAN); + g_value_set_boolean (value, entry->visible); + return; + case SWFEDIT_COLUMN_VALUE: + g_value_init (value, G_TYPE_STRING); + if (converters[entry->type].to_string) + g_value_take_string (value, converters[entry->type].to_string (entry->value)); + return; + default: + break; + } + g_assert_not_reached (); +} + +static gboolean +swfedit_token_iter_next (GtkTreeModel *tree_model, GtkTreeIter *iter) +{ + SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data); + int i; + + REPORT; + i = GPOINTER_TO_INT (iter->user_data2) + 1; + if ((guint) i >= token->tokens->len) + return FALSE; + + iter->user_data2 = GINT_TO_POINTER (i); + return TRUE; +} + +static gboolean +swfedit_token_iter_children (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent) +{ + SwfeditToken *token; + SwfeditTokenEntry *entry; + + REPORT; + if (parent) { + token = SWFEDIT_TOKEN (parent->user_data); + entry = &g_array_index (token->tokens, SwfeditTokenEntry, GPOINTER_TO_INT (parent->user_data2)); + if (entry->type != SWFEDIT_TOKEN_OBJECT) + return FALSE; + token = entry->value; + } else { + token = SWFEDIT_TOKEN (tree_model); + } + if (token->tokens->len == 0) + return FALSE; + iter->stamp = 0; /* FIXME */ + iter->user_data = token; + iter->user_data2 = GINT_TO_POINTER (0); + return TRUE; +} + +static gboolean +swfedit_token_iter_has_child (GtkTreeModel *tree_model, GtkTreeIter *iter) +{ + SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data); + SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, GPOINTER_TO_INT (iter->user_data2)); + + REPORT; + return entry->type == SWFEDIT_TOKEN_OBJECT && SWFEDIT_TOKEN (entry->value)->tokens->len > 0; +} + +static gint +swfedit_token_iter_n_children (GtkTreeModel *tree_model, GtkTreeIter *iter) +{ + SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data); + SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, GPOINTER_TO_INT (iter->user_data2)); + + REPORT; + if (entry->type != SWFEDIT_TOKEN_OBJECT) + return 0; + + token = entry->value; + return token->tokens->len; +} + +static gboolean +swfedit_token_iter_nth_child (GtkTreeModel *tree_model, GtkTreeIter *iter, + GtkTreeIter *parent, gint n) +{ + SwfeditToken *token; + SwfeditTokenEntry *entry; + + REPORT; + if (parent) { + token = SWFEDIT_TOKEN (parent->user_data); + entry = &g_array_index (token->tokens, SwfeditTokenEntry, GPOINTER_TO_INT (parent->user_data2)); + + if (entry->type != SWFEDIT_TOKEN_OBJECT) + return FALSE; + + token = entry->value; + } else { + token = SWFEDIT_TOKEN (tree_model); + } + if ((guint) n >= token->tokens->len) + return FALSE; + iter->stamp = 0; /* FIXME */ + iter->user_data = token; + iter->user_data2 = GINT_TO_POINTER (n); + return TRUE; +} + +static gboolean +swfedit_token_iter_parent (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child) +{ + guint i; + SwfeditToken *token = SWFEDIT_TOKEN (child->user_data); + SwfeditToken *parent = token->parent; + + REPORT; + if (parent == NULL) + return FALSE; + + for (i = 0; i < parent->tokens->len; i++) { + SwfeditTokenEntry *entry = &g_array_index (parent->tokens, SwfeditTokenEntry, i); + if (entry->type != SWFEDIT_TOKEN_OBJECT) + continue; + if (entry->value == token) + break; + } + iter->stamp = 0; /* FIXME */ + iter->user_data = parent; + iter->user_data2 = GINT_TO_POINTER (i); + return TRUE; +} + +static void +swfedit_token_tree_model_init (GtkTreeModelIface *iface) +{ + iface->get_flags = swfedit_token_get_flags; + iface->get_n_columns = swfedit_token_get_n_columns; + iface->get_column_type = swfedit_token_get_column_type; + iface->get_iter = swfedit_token_get_iter; + iface->get_path = swfedit_token_get_path; + iface->get_value = swfedit_token_get_value; + iface->iter_next = swfedit_token_iter_next; + iface->iter_children = swfedit_token_iter_children; + iface->iter_has_child = swfedit_token_iter_has_child; + iface->iter_n_children = swfedit_token_iter_n_children; + iface->iter_nth_child = swfedit_token_iter_nth_child; + iface->iter_parent = swfedit_token_iter_parent; +} + +/*** SWFEDIT_TOKEN ***/ + +G_DEFINE_TYPE_WITH_CODE (SwfeditToken, swfedit_token, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL, swfedit_token_tree_model_init)) + +static void +swfedit_token_dispose (GObject *object) +{ + SwfeditToken *token = SWFEDIT_TOKEN (object); + guint i; + + for (i = 0; i < token->tokens->len; i++) { + SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, i); + g_free (entry->name); + if (converters[entry->type].free) + converters[entry->type].free (entry->value); + } + g_array_free (token->tokens, TRUE); + + G_OBJECT_CLASS (swfedit_token_parent_class)->dispose (object); +} + +static void +swfedit_token_class_init (SwfeditTokenClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->dispose = swfedit_token_dispose; +} + +static void +swfedit_token_init (SwfeditToken *token) +{ + token->tokens = g_array_new (FALSE, FALSE, sizeof (SwfeditTokenEntry)); +} + +SwfeditToken * +swfedit_token_new (void) +{ + SwfeditToken *token; + + token = g_object_new (SWFEDIT_TYPE_TOKEN, NULL); + return token; +} + +void +swfedit_token_add (SwfeditToken *token, const char *name, SwfeditTokenType type, + gpointer value) +{ + SwfeditTokenEntry entry = { NULL, type, value, TRUE }; + + g_return_if_fail (SWFEDIT_IS_TOKEN (token)); + g_return_if_fail (name != NULL); + g_return_if_fail (type < SWFEDIT_N_TOKENS); + + g_assert (type != SWFEDIT_TOKEN_OBJECT || value != NULL); + entry.name = g_strdup (name); + g_array_append_val (token->tokens, entry); +} + +void +swfedit_token_set (SwfeditToken *token, guint i, gpointer value) +{ + SwfeditTokenClass *klass; + SwfeditTokenEntry *entry; + GtkTreePath *path; + SwfeditToken *model; + GtkTreeIter iter; + + g_return_if_fail (SWFEDIT_IS_TOKEN (token)); + g_return_if_fail (i < token->tokens->len); + + entry = &g_array_index (token->tokens, SwfeditTokenEntry, i); + if (converters[entry->type].free != NULL) + converters[entry->type].free (entry->value); + entry->value = value; + klass = SWFEDIT_TOKEN_GET_CLASS (token); + if (klass->changed) + klass->changed (token, i); + + model = token; + while (model->parent) + model = model->parent; + iter.user_data = token; + iter.user_data2 = GUINT_TO_POINTER (i); + path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter); + gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter); + gtk_tree_path_free (path); +} + +void +swfedit_token_set_iter (SwfeditToken *token, GtkTreeIter *iter, const char *value) +{ + SwfeditTokenClass *klass; + GtkTreeModel *model; + SwfeditTokenEntry *entry; + guint i; + gpointer new; + GtkTreePath *path; + + g_return_if_fail (SWFEDIT_IS_TOKEN (token)); + g_return_if_fail (iter != NULL); + g_return_if_fail (value != NULL); + + model = GTK_TREE_MODEL (token); + token = iter->user_data; + i = GPOINTER_TO_UINT (iter->user_data2); + entry = &g_array_index (token->tokens, SwfeditTokenEntry, i); + if (converters[entry->type].from_string == NULL) + return; + if (!converters[entry->type].from_string (value, &new)) + return; + if (converters[entry->type].free != NULL) + converters[entry->type].free (entry->value); + entry->value = new; + klass = SWFEDIT_TOKEN_GET_CLASS (token); + if (klass->changed) + klass->changed (token, i); + + path = gtk_tree_model_get_path (model, iter); + gtk_tree_model_row_changed (model, path, iter); + gtk_tree_path_free (path); +} + +void +swfedit_token_set_visible (SwfeditToken *token, guint i, gboolean visible) +{ + SwfeditTokenEntry *entry; + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + + g_return_if_fail (SWFEDIT_IS_TOKEN (token)); + g_return_if_fail (i < token->tokens->len); + + entry = &g_array_index (token->tokens, SwfeditTokenEntry, i); + if (entry->visible == visible) + return; + + entry->visible = visible; + iter.stamp = 0; /* FIXME */ + iter.user_data = token; + iter.user_data2 = GINT_TO_POINTER (i); + while (token->parent) + token = token->parent; + model = GTK_TREE_MODEL (token); + path = gtk_tree_model_get_path (model, &iter); + gtk_tree_model_row_changed (model, path, &iter); + gtk_tree_path_free (path); +} diff --git a/tools/swfedit_token.h b/tools/swfedit_token.h new file mode 100644 index 0000000..448f4cb --- /dev/null +++ b/tools/swfedit_token.h @@ -0,0 +1,109 @@ +/* Swfedit + * 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 __SWFEDIT_TOKEN_H__ +#define __SWFEDIT_TOKEN_H__ + +#include <gtk/gtk.h> +#include <libswfdec/swfdec_rect.h> + +G_BEGIN_DECLS + +typedef enum { + SWFEDIT_TOKEN_OBJECT, + SWFEDIT_TOKEN_BINARY, + SWFEDIT_TOKEN_BIT, + SWFEDIT_TOKEN_UINT8, + SWFEDIT_TOKEN_UINT16, + SWFEDIT_TOKEN_UINT32, + SWFEDIT_TOKEN_STRING, + SWFEDIT_TOKEN_RECT, + SWFEDIT_TOKEN_RGB, + SWFEDIT_TOKEN_RGBA, + SWFEDIT_TOKEN_MATRIX, + SWFEDIT_TOKEN_CTRANS, + SWFEDIT_TOKEN_SCRIPT, + SWFEDIT_TOKEN_CLIPEVENTFLAGS, + SWFEDIT_N_TOKENS +} SwfeditTokenType; + +typedef enum { + SWFEDIT_COLUMN_NAME, + SWFEDIT_COLUMN_VALUE_VISIBLE, + SWFEDIT_COLUMN_VALUE, + SWFEDIT_COLUMN_VALUE_EDITABLE +} SwfeditColumn; + +typedef struct _SwfeditTokenEntry SwfeditTokenEntry; + +typedef struct _SwfeditToken SwfeditToken; +typedef struct _SwfeditTokenClass SwfeditTokenClass; + +#define SWFEDIT_TYPE_TOKEN (swfedit_token_get_type()) +#define SWFEDIT_IS_TOKEN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFEDIT_TYPE_TOKEN)) +#define SWFEDIT_IS_TOKEN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFEDIT_TYPE_TOKEN)) +#define SWFEDIT_TOKEN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFEDIT_TYPE_TOKEN, SwfeditToken)) +#define SWFEDIT_TOKEN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFEDIT_TYPE_TOKEN, SwfeditTokenClass)) +#define SWFEDIT_TOKEN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFEDIT_TYPE_TOKEN, SwfeditTokenClass)) + +struct _SwfeditTokenEntry { + char * name; + SwfeditTokenType type; + gpointer value; + gboolean visible; +}; + +struct _SwfeditToken { + GObject object; + + SwfeditToken * parent; /* parent of this token or NULL */ + gchar * name; /* name of token */ + GArray * tokens; /* of SwfeditTokenEntry */ +}; + +struct _SwfeditTokenClass { + GObjectClass object_class; + + void (* changed) (SwfeditToken * token, + guint id); +}; + +GType swfedit_token_get_type (void); + +gpointer swfedit_token_new_token (SwfeditTokenType type); + +SwfeditToken * swfedit_token_new (void); +void swfedit_token_add (SwfeditToken * token, + const char * name, + SwfeditTokenType type, + gpointer value); +void swfedit_token_set (SwfeditToken * token, + guint i, + gpointer value); +void swfedit_token_set_iter (SwfeditToken * token, + GtkTreeIter * iter, + const char * value); +void swfedit_token_set_visible (SwfeditToken * token, + guint i, + gboolean visible); + + +G_END_DECLS + +#endif diff --git a/tools/swfscript.c b/tools/swfscript.c new file mode 100644 index 0000000..4e2a9e4 --- /dev/null +++ b/tools/swfscript.c @@ -0,0 +1,298 @@ +/* Swfedit + * 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 <gtk/gtk.h> +#include "libswfdec/swfdec_script_internal.h" +#include "swfdec_out.h" +#include "swfedit_file.h" + +/* the stuff we look for */ +guint *add_trace = NULL; + +typedef gboolean ( *SwfeditTokenForeachFunc) (SwfeditToken *token, guint idx, + const char *name, SwfeditTokenType type, gconstpointer value, gpointer data); + +static gboolean +swfedit_token_foreach (SwfeditToken *token, SwfeditTokenForeachFunc func, + gpointer data) +{ + SwfeditTokenEntry *entry; + guint i; + + g_return_val_if_fail (SWFEDIT_IS_TOKEN (token), FALSE); + g_return_val_if_fail (func != NULL, FALSE); + + for (i = 0; i < token->tokens->len; i++) { + entry = &g_array_index (token->tokens, SwfeditTokenEntry, i); + if (!func (token, i, entry->name, entry->type, entry->value, data)) + return FALSE; + if (entry->type == SWFEDIT_TOKEN_OBJECT) { + if (!swfedit_token_foreach (entry->value, func, data)) + return FALSE; + } + } + return TRUE; +} + +typedef struct { + guint offset; /* offset in bytes from start of script */ + guint new_offset; /* new offset in bytes from start of script */ + guint new_actions; /* number of actions in new script */ +} Action; + +typedef struct { + SwfdecScript * script; /* the original script */ + SwfdecOut * out; /* output for new script or NULL when buffer is set */ + SwfdecBuffer * buffer; /* buffer containing new script or NULL while constructing */ + GArray * actions; /* all actions in the script */ +} State; + +static gboolean +action_in_array (guint *array, guint action) +{ + if (array == NULL) + return FALSE; + while (*array != 0) { + if (*array == action) + return TRUE; + array++; + } + return FALSE; +} + +static guint +lookup_offset (GArray *array, guint offset) +{ + guint i; + for (i = 0; i < array->len; i++) { + Action *action = &g_array_index (array, Action, i); + if (action->offset == offset) + return action->new_offset; + } + g_assert_not_reached (); + return 0; +} + +static gboolean +fixup_jumps_foreach (gconstpointer bytecode, guint action, + const guint8 *data, guint len, gpointer user_data) +{ + State *state = user_data; + + if (action == 0x99 || action == 0x9d) { + guint offset = (guint8 *) bytecode - state->script->buffer->data; + guint jump_offset = offset + 5 + GINT16_FROM_LE (*((gint16 *) data)); + offset = lookup_offset (state->actions, offset); + jump_offset = lookup_offset (state->actions, jump_offset); + *((gint16 *) &state->buffer->data[offset + 3]) = + GINT16_TO_LE (jump_offset - offset - 5); + } + if (action == 0x8a || action == 0x8d) { + Action *cur = NULL; /* silence gcc */ + guint id = action == 0x8a ? 2 : 0; + guint i, count; + guint offset = (guint8 *) bytecode - state->script->buffer->data; + for (i = 0; i < state->actions->len; i++) { + cur = &g_array_index (state->actions, Action, i); + if (cur->offset == offset) { + offset = cur->new_offset; + break; + } + } + g_assert (i < state->actions->len); + i = data[id]; + count = cur->new_actions - 1; /* FIXME: only works as long as we append actions */ + while (i > 0) { + cur++; + count += cur->new_actions; + i--; + } + g_assert (count < 256); + state->buffer->data[offset + 3 + id] = count; + } + return TRUE; +} + +static gboolean +modify_script_foreach (gconstpointer bytecode, guint action, + const guint8 *data, guint len, gpointer user_data) +{ + Action next; + State *state = user_data; + + next.offset = (guint8 *) bytecode - state->script->buffer->data; + next.new_offset = swfdec_out_get_bits (state->out) / 8; + next.new_actions = 1; + swfdec_out_put_u8 (state->out, action); + if (action & 0x80) { + swfdec_out_put_u16 (state->out, len); + swfdec_out_put_data (state->out, data, len); + } + if (action_in_array (add_trace, action)) { + swfdec_out_put_u8 (state->out, 0x4c); /* PushDuplicate */ + swfdec_out_put_u8 (state->out, 0x26); /* Trace */ + next.new_actions += 2; + } + g_array_append_val (state->actions, next); + return TRUE; +} + +static gboolean +modify_file (SwfeditToken *token, guint idx, const char *name, + SwfeditTokenType type, gconstpointer value, gpointer data) +{ + Action end; + SwfdecScript *script; + State state; + + if (type != SWFEDIT_TOKEN_SCRIPT) + return TRUE; + + state.script = (SwfdecScript *) value; + state.out = swfdec_out_open (); + state.buffer = NULL; + state.actions = g_array_new (FALSE, FALSE, sizeof (Action)); + swfdec_script_foreach (state.script, modify_script_foreach, &state); + /* compute end offset */ + end.offset = g_array_index (state.actions, Action, state.actions->len - 1).offset; + if (state.script->buffer->data[end.offset] & 0x80) { + end.offset += GUINT16_FROM_LE (*((guint16* ) &state.script->buffer->data[end.offset + 1])) + 3; + } else { + end.offset++; + } + end.new_offset = swfdec_out_get_bits (state.out) / 8; + end.new_actions = 0; + g_array_append_val (state.actions, end); +#if 0 + { + guint i; + for (i = 0; i < state.actions->len; i++) { + Action *action = &g_array_index (state.actions, Action, i); + g_print ("%u %u => %u (%u actions)\n", i, action->offset, + action->new_offset, action->new_actions); + } + } +#endif + /* maybe append 0 byte */ + if (end.offset + 1 == state.script->buffer->length) { + swfdec_out_put_u8 (state.out, 0); + } else { + g_assert (end.offset == state.script->buffer->length); + } + state.buffer = swfdec_out_close (state.out); + state.out = NULL; + swfdec_script_foreach (state.script, fixup_jumps_foreach, &state); + g_array_free (state.actions, TRUE); +#if 0 + g_print ("got a new script in %u bytes - old script was %u bytes\n", + state.buffer->length, state.script->buffer->length); +#endif + script = swfdec_script_new (state.buffer, state.script->name, state.script->version); + g_assert (script); + swfedit_token_set (token, idx, script); + + return TRUE; +} + +static guint * +string_to_action_list (const char *list) +{ + char **actions = g_strsplit (list, ",", -1); + guint *ret; + guint i, len; + + len = g_strv_length (actions); + ret = g_new (guint, len + 1); + ret[len] = 0; + for (i = 0; i < len; i++) { + ret[i] = swfdec_action_get_from_name (actions[i]); + if (ret[i] == 0) { + g_printerr ("No such action \"%s\"\n", actions[i]); + g_free (actions); + g_free (ret); + return NULL; + } + } + g_free (actions); + return ret; +} + +int +main (int argc, char **argv) +{ + SwfeditFile *file; + GError *error = NULL; + char *add_trace_s = NULL; + GOptionEntry options[] = { + { "add-trace", 't', 0, G_OPTION_ARG_STRING, &add_trace_s, "list of actions to trace", "ACTION, ACTION" }, + { NULL } + }; + GOptionContext *ctx; + + ctx = g_option_context_new (""); + g_option_context_add_main_entries (ctx, options, "options"); + g_option_context_add_group (ctx, gtk_get_option_group (TRUE)); + g_option_context_parse (ctx, &argc, &argv, &error); + g_option_context_free (ctx); + if (error) { + g_printerr ("error parsing arguments: %s\n", error->message); + g_error_free (error); + return 1; + } + + if (argc < 2) { + g_printerr ("Usage: %s FILENAME [OUTPUT-FILENAME]\n", argv[0]); + return 1; + } + if (add_trace_s) { + add_trace = string_to_action_list (add_trace_s); + g_free (add_trace_s); + if (add_trace == NULL) + return 1; + } + file = swfedit_file_new (argv[1], &error); + if (file == NULL) { + g_printerr ("error opening file %s: %s\n", argv[1], error->message); + g_error_free (error); + return 1; + } + if (!swfedit_token_foreach (SWFEDIT_TOKEN (file), modify_file, NULL)) { + g_printerr ("modifying file %s failed.\n", argv[1]); + g_object_unref (file); + return 1; + } + g_free (file->filename); + if (argc > 2) { + file->filename = g_strdup (argv[2]); + } else { + file->filename = g_strdup_printf ("%s.out.swf", argv[1]); + } + if (!swfedit_file_save (file, &error)) { + g_printerr ("Error saving file: %s\n", error->message); + g_error_free (error); + } + g_print ("saved modified file to %s\n", file->filename); + g_object_unref (file); + return 0; +} + commit 82495a0102e01a1706933f10696daed163692a71 Author: Benjamin Otte <otte at gnome.org> Date: Mon Jan 7 19:38:20 2008 +0100 update types list That has been forgotten for a long time... diff --git a/doc/swfdec.types b/doc/swfdec.types index 9b70671..c89c6d5 100644 --- a/doc/swfdec.types +++ b/doc/swfdec.types @@ -1,9 +1,15 @@ #include <libswfdec/swfdec.h> #include <libswfdec-gtk/swfdec-gtk.h> -swfdec_player_get_type +swfdec_as_context_get_type +swfdec_as_object_get_type +swfdec_as_frame_get_type +swfdec_as_function_get_type swfdec_audio_get_type swfdec_loader_get_type +swfdec_player_get_type +swfdec_player_scripting_get_type +swfdec_system_get_type swfdec_gtk_loader_get_type swfdec_gtk_player_get_type swfdec_gtk_widget_get_type commit a9d0e147d2889ed8d4c26bdcfde68d63187cbd6c Author: Benjamin Otte <otte at gnome.org> Date: Mon Jan 7 19:09:30 2008 +0100 add tracing support diff --git a/test/test/swfdec_test_test.c b/test/test/swfdec_test_test.c index 2739204..04c6402 100644 --- a/test/test/swfdec_test_test.c +++ b/test/test/swfdec_test_test.c @@ -21,12 +21,112 @@ #include "config.h" #endif +#include <string.h> + #include "swfdec_test_test.h" #include "swfdec_test_function.h" +static void +swfdec_test_throw (SwfdecAsContext *cx, const char *message, ...) +{ + SwfdecAsValue val; + + if (!swfdec_as_context_catch (cx, &val)) { + va_list varargs; + char *s; + + va_start (varargs, message); + s = g_strdup_vprintf (message, varargs); + va_end (varargs); + + /* FIXME: Throw a real object here? */ + SWFDEC_AS_VALUE_SET_STRING (&val, swfdec_as_context_give_string (cx, s)); + } + swfdec_as_context_throw (cx, &val); +} + /*** trace capturing ***/ +static void +swfdec_test_test_trace_stop (SwfdecTestTest *test) +{ + if (test->trace_filename == NULL) + return; + + if (test->trace_buffer && + test->trace_offset != test->trace_buffer->data + test->trace_buffer->length) + test->trace_failed = TRUE; + + if (test->trace_failed) { + /* FIXME: produce a diff here */ + swfdec_test_throw (SWFDEC_AS_OBJECT (test)->context, "invalid trace output"); + } + + if (test->trace_buffer) { + swfdec_buffer_unref (test->trace_buffer); + test->trace_buffer = NULL; + } + g_free (test->trace_filename); + test->trace_filename = NULL; +} + +static void +swfdec_test_test_trace_start (SwfdecTestTest *test, const char *filename) +{ + GError *error = NULL; + + g_assert (test->trace_filename == NULL); + + test->trace_filename = g_strdup (filename); + test->trace_buffer = swfdec_buffer_new_from_file (filename, &error); + if (test->trace_buffer == NULL) { + swfdec_test_throw (SWFDEC_AS_OBJECT (test)->context, "Could not start trace: %s", error->message); + g_error_free (error); + return; + } + test->trace_offset = test->trace_buffer->data; +} + +static void +swfdec_test_test_trace_cb (SwfdecPlayer *player, const char *message, SwfdecTestTest *test) +{ + gsize len; + + if (test->trace_buffer == NULL || test->trace_failed) + return; + len = strlen (message); + if (len + 1 > test->trace_buffer->length - (test->trace_offset -test->trace_buffer->data)) { + test->trace_failed = TRUE; + return; + } + if (memcmp (message, test->trace_offset, len) != 0) { + test->trace_failed = TRUE; + return; + } + test->trace_offset += len; + if (test->trace_offset[0] != '\n') { + test->trace_failed = TRUE; + return; + } + test->trace_offset++; +} + +SWFDEC_TEST_FUNCTION ("Test_trace", swfdec_test_test_trace, 0) +void +swfdec_test_test_trace (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, + SwfdecAsValue *argv, SwfdecAsValue *retval) +{ + SwfdecTestTest *test; + const char *filename; + + SWFDEC_AS_CHECK (SWFDEC_TYPE_TEST_TEST, &test, "|s", &filename); + + swfdec_test_test_trace_stop (test); + if (filename[0] == '\0') + return; + swfdec_test_test_trace_start (test, filename); +} /*** SWFDEC_TEST_TEST ***/ @@ -37,9 +137,13 @@ swfdec_test_test_dispose (GObject *object) { SwfdecTestTest *test = SWFDEC_TEST_TEST (object); + /* FIXME: this can throw, is that ok? */ + swfdec_test_test_trace_stop (test); + g_free (test->filename); test->filename = NULL; if (test->player) { + g_signal_handlers_disconnect_matched (test, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, test); g_object_unref (test->player); test->player = NULL; } @@ -60,20 +164,6 @@ swfdec_test_test_init (SwfdecTestTest *this) { } -#if 0 -static void -swfdec_test_throw (SwfdecAsContext *cx, const char *error) -{ - SwfdecAsValue val; - - if (!swfdec_as_context_catch (cx, &val)) { - /* FIXME: Throw a real object here? */ - SWFDEC_AS_VALUE_SET_STRING (&val, swfdec_as_context_get_string (cx, error)); - } - swfdec_as_context_throw (cx, &val); -} -#endif - static void swfdec_test_test_fscommand (SwfdecPlayer *player, const char *command, const char *para, SwfdecTestTest *test) @@ -91,6 +181,7 @@ swfdec_test_test_ensure_player (SwfdecTestTest *test) test->player = swfdec_player_new_from_file (test->filename); g_signal_connect (test, "fscommand", G_CALLBACK (swfdec_test_test_fscommand), test); + g_signal_connect (test, "trace", G_CALLBACK (swfdec_test_test_trace_cb), test); return TRUE; } @@ -98,6 +189,7 @@ static void swfdec_test_do_reset (SwfdecTestTest *test, const char *filename) { if (test->player) { + g_signal_handlers_disconnect_matched (test, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, test); g_object_unref (test->player); test->player = NULL; } @@ -153,7 +245,7 @@ swfdec_test_test_new (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SWFDEC_AS_CHECK (SWFDEC_TYPE_TEST_TEST, &test, "|s", &filename); - swfdec_test_do_reset (test, filename); + swfdec_test_do_reset (test, filename[0] ? filename : NULL); } SWFDEC_TEST_FUNCTION ("Test_rate", swfdec_test_test_get_rate, 0) diff --git a/test/test/swfdec_test_test.h b/test/test/swfdec_test_test.h index 7172897..6218f31 100644 --- a/test/test/swfdec_test_test.h +++ b/test/test/swfdec_test_test.h @@ -42,6 +42,12 @@ struct _SwfdecTestTest char * filename; /* file the player should be loaded from */ SwfdecPlayer * player; /* the player or %NULL if none */ gboolean player_quit; /* the player has called fscommand:quit */ + + /* trace stuff */ + char * trace_filename; /* file we're parsing */ + SwfdecBuffer * trace_buffer; /* buffer containing the file */ + guchar * trace_offset; /* how far we've parsed the trace data */ + gboolean trace_failed; /* TRUE if the tacing failed */ }; struct _SwfdecTestTestClass commit 58323f9f4d7764038f17767bffaa05f99d77b4cf Author: Benjamin Otte <otte at gnome.org> Date: Mon Jan 7 19:09:19 2008 +0100 add some more functions diff --git a/test/test/swfdec_test_initialize.as b/test/test/swfdec_test_initialize.as index 03eab16..338fdf0 100644 --- a/test/test/swfdec_test_initialize.as +++ b/test/test/swfdec_test_initialize.as @@ -18,11 +18,17 @@ */ Test = Native.Test; -Test.reset = Native.Test_reset; Test.prototype = {}; +Test.prototype.advance = Native.Test_advance; +Test.prototype.reset = Native.Test_reset; +Test.prototype.trace = Native.Test_trace; Test.prototype.addProperty ("rate", Native.Test_get_rate, null); print = function (s) { if (s) Native.print ("INFO: " + s); }; +error = function (s) { + if (s) + Native.print ("ERROR: " + s); +}; diff --git a/test/test/swfdec_test_initialize.h b/test/test/swfdec_test_initialize.h index ff3ef4f..a7dc1f4 100644 --- a/test/test/swfdec_test_initialize.h +++ b/test/test/swfdec_test_initialize.h @@ -2,20 +2,31 @@ /* compiled from swfdec_test_initialize.as */ static const unsigned char swfdec_test_initialize[] = { - 0x88, 0x57, 0x00, 0x0B, 0x00, 0x54, 0x65, 0x73, 0x74, 0x00, 0x4E, 0x61, 0x74, 0x69, 0x76, 0x65, - 0x00, 0x72, 0x65, 0x73, 0x65, 0x74, 0x00, 0x54, 0x65, 0x73, 0x74, 0x5F, 0x72, 0x65, 0x73, 0x65, - 0x74, 0x00, 0x70, 0x72, 0x6F, 0x74, 0x6F, 0x74, 0x79, 0x70, 0x65, 0x00, 0x72, 0x61, 0x74, 0x65, - 0x00, 0x54, 0x65, 0x73, 0x74, 0x5F, 0x67, 0x65, 0x74, 0x5F, 0x72, 0x61, 0x74, 0x65, 0x00, 0x61, - 0x64, 0x64, 0x50, 0x72, 0x6F, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x70, 0x72, 0x69, 0x6E, 0x74, - 0x00, 0x73, 0x00, 0x49, 0x4E, 0x46, 0x4F, 0x3A, 0x20, 0x00, 0x96, 0x04, 0x00, 0x08, 0x00, 0x08, - 0x01, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x00, 0x4E, 0x1D, 0x96, 0x02, 0x00, 0x08, 0x00, 0x1C, 0x96, - 0x04, 0x00, 0x08, 0x02, 0x08, 0x01, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x03, 0x4E, 0x4F, 0x96, 0x02, - 0x00, 0x08, 0x00, 0x1C, 0x96, 0x07, 0x00, 0x08, 0x04, 0x07, 0x00, 0x00, 0x00, 0x00, 0x43, 0x4F, - 0x96, 0x03, 0x00, 0x02, 0x08, 0x01, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x06, 0x4E, 0x96, 0x09, 0x00, - 0x08, 0x05, 0x07, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x04, 0x4E, - 0x96, 0x02, 0x00, 0x08, 0x07, 0x52, 0x17, 0x96, 0x02, 0x00, 0x08, 0x08, 0x9B, 0x07, 0x00, 0x00, - 0x01, 0x00, 0x73, 0x00, 0x27, 0x00, 0x96, 0x02, 0x00, 0x08, 0x09, 0x1C, 0x12, 0x9D, 0x02, 0x00, - 0x1B, 0x00, 0x96, 0x04, 0x00, 0x08, 0x0A, 0x08, 0x09, 0x1C, 0x47, 0x96, 0x07, 0x00, 0x07, 0x01, - 0x00, 0x00, 0x00, 0x08, 0x01, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x08, 0x52, 0x17, 0x1D, 0x00 + 0x88, 0x8B, 0x00, 0x11, 0x00, 0x54, 0x65, 0x73, 0x74, 0x00, 0x4E, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x00, 0x70, 0x72, 0x6F, 0x74, 0x6F, 0x74, 0x79, 0x70, 0x65, 0x00, 0x61, 0x64, 0x76, 0x61, 0x6E, + 0x63, 0x65, 0x00, 0x54, 0x65, 0x73, 0x74, 0x5F, 0x61, 0x64, 0x76, 0x61, 0x6E, 0x63, 0x65, 0x00, + 0x72, 0x65, 0x73, 0x65, 0x74, 0x00, 0x54, 0x65, 0x73, 0x74, 0x5F, 0x72, 0x65, 0x73, 0x65, 0x74, + 0x00, 0x74, 0x72, 0x61, 0x63, 0x65, 0x00, 0x54, 0x65, 0x73, 0x74, 0x5F, 0x74, 0x72, 0x61, 0x63, + 0x65, 0x00, 0x72, 0x61, 0x74, 0x65, 0x00, 0x54, 0x65, 0x73, 0x74, 0x5F, 0x67, 0x65, 0x74, 0x5F, + 0x72, 0x61, 0x74, 0x65, 0x00, 0x61, 0x64, 0x64, 0x50, 0x72, 0x6F, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x00, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x00, 0x73, 0x00, 0x49, 0x4E, 0x46, 0x4F, 0x3A, 0x20, 0x00, + 0x65, 0x72, 0x72, 0x6F, 0x72, 0x00, 0x45, 0x52, 0x52, 0x4F, 0x52, 0x3A, 0x20, 0x00, 0x96, 0x04, + 0x00, 0x08, 0x00, 0x08, 0x01, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x00, 0x4E, 0x1D, 0x96, 0x02, 0x00, + 0x08, 0x00, 0x1C, 0x96, 0x07, 0x00, 0x08, 0x02, 0x07, 0x00, 0x00, 0x00, 0x00, 0x43, 0x4F, 0x96, + 0x02, 0x00, 0x08, 0x00, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x02, 0x4E, 0x96, 0x04, 0x00, 0x08, 0x03, + 0x08, 0x01, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x04, 0x4E, 0x4F, 0x96, 0x02, 0x00, 0x08, 0x00, 0x1C, + 0x96, 0x02, 0x00, 0x08, 0x02, 0x4E, 0x96, 0x04, 0x00, 0x08, 0x05, 0x08, 0x01, 0x1C, 0x96, 0x02, + 0x00, 0x08, 0x06, 0x4E, 0x4F, 0x96, 0x02, 0x00, 0x08, 0x00, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x02, + 0x4E, 0x96, 0x04, 0x00, 0x08, 0x07, 0x08, 0x01, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x08, 0x4E, 0x4F, + 0x96, 0x03, 0x00, 0x02, 0x08, 0x01, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x0A, 0x4E, 0x96, 0x09, 0x00, + 0x08, 0x09, 0x07, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x02, 0x4E, + 0x96, 0x02, 0x00, 0x08, 0x0B, 0x52, 0x17, 0x96, 0x02, 0x00, 0x08, 0x0C, 0x9B, 0x07, 0x00, 0x00, + 0x01, 0x00, 0x73, 0x00, 0x27, 0x00, 0x96, 0x02, 0x00, 0x08, 0x0D, 0x1C, 0x12, 0x9D, 0x02, 0x00, + 0x1B, 0x00, 0x96, 0x04, 0x00, 0x08, 0x0E, 0x08, 0x0D, 0x1C, 0x47, 0x96, 0x07, 0x00, 0x07, 0x01, + 0x00, 0x00, 0x00, 0x08, 0x01, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x0C, 0x52, 0x17, 0x1D, 0x96, 0x02, + 0x00, 0x08, 0x0F, 0x9B, 0x07, 0x00, 0x00, 0x01, 0x00, 0x73, 0x00, 0x27, 0x00, 0x96, 0x02, 0x00, + 0x08, 0x0D, 0x1C, 0x12, 0x9D, 0x02, 0x00, 0x1B, 0x00, 0x96, 0x04, 0x00, 0x08, 0x10, 0x08, 0x0D, + 0x1C, 0x47, 0x96, 0x07, 0x00, 0x07, 0x01, 0x00, 0x00, 0x00, 0x08, 0x01, 0x1C, 0x96, 0x02, 0x00, + 0x08, 0x0C, 0x52, 0x17, 0x1D, 0x00 }; commit 7f948781726765ba56e96136b7ad8c65d34ad13d Author: Benjamin Otte <otte at gnome.org> Date: Mon Jan 7 19:06:28 2008 +0100 compile script as version 8 diff --git a/test/test/compiler.c b/test/test/compiler.c index ce0ef12..f4e0fcb 100644 --- a/test/test/compiler.c +++ b/test/test/compiler.c @@ -21,7 +21,7 @@ main (int argc, char **argv) SWFAction action; char *contents; GError *error = NULL; - gsize len; + int len; byte *data; if (argc != 3) { @@ -38,7 +38,11 @@ main (int argc, char **argv) return 1; } action = newSWFAction (contents); - data = SWFAction_getByteCode (action, &len); + if (SWFAction_compile (action, 8, &len) != 0) { + g_printerr ("compilation failed\n"); + return 1; + } + data = SWFAction_getByteCode (action, NULL); contents = g_malloc (len + sizeof (HEADER)); memcpy (contents, HEADER, sizeof (HEADER)); memcpy (contents + sizeof (HEADER), data, len); commit b5e2671fbbcd142100dbaa22a735655b4a971267 Author: Benjamin Otte <otte at gnome.org> Date: Mon Jan 7 18:30:43 2008 +0100 This should be a pointer to a string here diff --git a/test/test/swfdec_test_global.c b/test/test/swfdec_test_global.c index 56c6317..6926944 100644 --- a/test/test/swfdec_test_global.c +++ b/test/test/swfdec_test_global.c @@ -33,7 +33,7 @@ swfdec_test_print (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, { const char *s; - SWFDEC_AS_CHECK (0, NULL, "s", s); + SWFDEC_AS_CHECK (0, NULL, "s", &s); g_print ("%s\n", s); } commit 93f761ed11e01b69e1793f9b9cbba6d45b82cee1 Author: Benjamin Otte <otte at gnome.org> Date: Mon Jan 7 17:48:27 2008 +0100 ignore autogenerated file diff --git a/test/test/.gitignore b/test/test/.gitignore index 7bd49f0..34dad19 100644 --- a/test/test/.gitignore +++ b/test/test/.gitignore @@ -1,2 +1,4 @@ +swfdec_test_function_list.h + compiler test commit 2d2654ba80b3fcc56c07f1364f0e5318c2605f25 Author: Benjamin Otte <otte at gnome.org> Date: Mon Jan 7 17:47:35 2008 +0100 add a test.rate property diff --git a/test/test/swfdec_test_initialize.as b/test/test/swfdec_test_initialize.as index 45d807b..03eab16 100644 --- a/test/test/swfdec_test_initialize.as +++ b/test/test/swfdec_test_initialize.as @@ -18,7 +18,9 @@ */ Test = Native.Test; -Test.reset = Native.reset; +Test.reset = Native.Test_reset; +Test.prototype = {}; +Test.prototype.addProperty ("rate", Native.Test_get_rate, null); print = function (s) { if (s) diff --git a/test/test/swfdec_test_initialize.h b/test/test/swfdec_test_initialize.h index 547e492..ff3ef4f 100644 --- a/test/test/swfdec_test_initialize.h +++ b/test/test/swfdec_test_initialize.h @@ -2,14 +2,20 @@ /* compiled from swfdec_test_initialize.as */ static const unsigned char swfdec_test_initialize[] = { - 0x88, 0x23, 0x00, 0x06, 0x00, 0x54, 0x65, 0x73, 0x74, 0x00, 0x4E, 0x61, 0x74, 0x69, 0x76, 0x65, - 0x00, 0x72, 0x65, 0x73, 0x65, 0x74, 0x00, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x00, 0x73, 0x00, 0x49, - 0x4E, 0x46, 0x4F, 0x3A, 0x20, 0x00, 0x96, 0x04, 0x00, 0x08, 0x00, 0x08, 0x01, 0x1C, 0x96, 0x02, - 0x00, 0x08, 0x00, 0x4E, 0x1D, 0x96, 0x02, 0x00, 0x08, 0x00, 0x1C, 0x96, 0x04, 0x00, 0x08, 0x02, - 0x08, 0x01, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x02, 0x4E, 0x4F, 0x96, 0x02, 0x00, 0x08, 0x03, 0x9B, - 0x07, 0x00, 0x00, 0x01, 0x00, 0x73, 0x00, 0x27, 0x00, 0x96, 0x02, 0x00, 0x08, 0x04, 0x1C, 0x12, - 0x9D, 0x02, 0x00, 0x1B, 0x00, 0x96, 0x04, 0x00, 0x08, 0x05, 0x08, 0x04, 0x1C, 0x47, 0x96, 0x07, - 0x00, 0x07, 0x01, 0x00, 0x00, 0x00, 0x08, 0x01, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x03, 0x52, 0x17, - 0x1D, 0x00 + 0x88, 0x57, 0x00, 0x0B, 0x00, 0x54, 0x65, 0x73, 0x74, 0x00, 0x4E, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x00, 0x72, 0x65, 0x73, 0x65, 0x74, 0x00, 0x54, 0x65, 0x73, 0x74, 0x5F, 0x72, 0x65, 0x73, 0x65, + 0x74, 0x00, 0x70, 0x72, 0x6F, 0x74, 0x6F, 0x74, 0x79, 0x70, 0x65, 0x00, 0x72, 0x61, 0x74, 0x65, + 0x00, 0x54, 0x65, 0x73, 0x74, 0x5F, 0x67, 0x65, 0x74, 0x5F, 0x72, 0x61, 0x74, 0x65, 0x00, 0x61, + 0x64, 0x64, 0x50, 0x72, 0x6F, 0x70, 0x65, 0x72, 0x74, 0x79, 0x00, 0x70, 0x72, 0x69, 0x6E, 0x74, + 0x00, 0x73, 0x00, 0x49, 0x4E, 0x46, 0x4F, 0x3A, 0x20, 0x00, 0x96, 0x04, 0x00, 0x08, 0x00, 0x08, + 0x01, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x00, 0x4E, 0x1D, 0x96, 0x02, 0x00, 0x08, 0x00, 0x1C, 0x96, + 0x04, 0x00, 0x08, 0x02, 0x08, 0x01, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x03, 0x4E, 0x4F, 0x96, 0x02, + 0x00, 0x08, 0x00, 0x1C, 0x96, 0x07, 0x00, 0x08, 0x04, 0x07, 0x00, 0x00, 0x00, 0x00, 0x43, 0x4F, + 0x96, 0x03, 0x00, 0x02, 0x08, 0x01, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x06, 0x4E, 0x96, 0x09, 0x00, + 0x08, 0x05, 0x07, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x04, 0x4E, + 0x96, 0x02, 0x00, 0x08, 0x07, 0x52, 0x17, 0x96, 0x02, 0x00, 0x08, 0x08, 0x9B, 0x07, 0x00, 0x00, + 0x01, 0x00, 0x73, 0x00, 0x27, 0x00, 0x96, 0x02, 0x00, 0x08, 0x09, 0x1C, 0x12, 0x9D, 0x02, 0x00, + 0x1B, 0x00, 0x96, 0x04, 0x00, 0x08, 0x0A, 0x08, 0x09, 0x1C, 0x47, 0x96, 0x07, 0x00, 0x07, 0x01, + 0x00, 0x00, 0x00, 0x08, 0x01, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x08, 0x52, 0x17, 0x1D, 0x00 }; diff --git a/test/test/swfdec_test_test.c b/test/test/swfdec_test_test.c index 74473ee..2739204 100644 --- a/test/test/swfdec_test_test.c +++ b/test/test/swfdec_test_test.c @@ -155,3 +155,16 @@ swfdec_test_test_new (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, swfdec_test_do_reset (test, filename); } + +SWFDEC_TEST_FUNCTION ("Test_rate", swfdec_test_test_get_rate, 0) +void +swfdec_test_test_get_rate (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, + SwfdecAsValue *argv, SwfdecAsValue *retval) +{ + SwfdecTestTest *test; + + SWFDEC_AS_CHECK (SWFDEC_TYPE_TEST_TEST, &test, ""); + + SWFDEC_AS_VALUE_SET_NUMBER (retval, test->player ? swfdec_player_get_rate (test->player) : 0); +} + commit 9185793d14379606672581a282839a56ca53c31e Author: Benjamin Otte <otte at gnome.org> Date: Mon Jan 7 17:43:25 2008 +0100 This file is autogenerated oops diff --git a/test/test/swfdec_test_function_list.h b/test/test/swfdec_test_function_list.h deleted file mode 100644 index 9ddf1c1..0000000 --- a/test/test/swfdec_test_function_list.h +++ /dev/null @@ -1,4 +0,0 @@ -SWFDEC_TEST_FUNCTION ("print", swfdec_test_print, 0) -SWFDEC_TEST_FUNCTION ("Test_advance", swfdec_test_test_advance, 0) -SWFDEC_TEST_FUNCTION ("Test_reset", swfdec_test_test_reset, 0) -SWFDEC_TEST_FUNCTION ("Test", swfdec_test_test_new, swfdec_test_test_get_type) commit 2ed69da82ede7d0ea800cbad4306e663a237078d Author: Benjamin Otte <otte at gnome.org> Date: Mon Jan 7 17:43:09 2008 +0100 add a global print function diff --git a/test/test/Makefile.am b/test/test/Makefile.am index 6bc3dac..b610daa 100644 --- a/test/test/Makefile.am +++ b/test/test/Makefile.am @@ -5,6 +5,7 @@ swfdec_test_sources = \ swfdec_test.c \ swfdec_test_function.c \ swfdec_test_function.h \ + swfdec_test_global.c \ swfdec_test_test.c \ swfdec_test_test.h diff --git a/test/test/swfdec_test_function_list.h b/test/test/swfdec_test_function_list.h index 46908ab..9ddf1c1 100644 --- a/test/test/swfdec_test_function_list.h +++ b/test/test/swfdec_test_function_list.h @@ -1,3 +1,4 @@ +SWFDEC_TEST_FUNCTION ("print", swfdec_test_print, 0) SWFDEC_TEST_FUNCTION ("Test_advance", swfdec_test_test_advance, 0) SWFDEC_TEST_FUNCTION ("Test_reset", swfdec_test_test_reset, 0) SWFDEC_TEST_FUNCTION ("Test", swfdec_test_test_new, swfdec_test_test_get_type) diff --git a/test/test/swfdec_test_global.c b/test/test/swfdec_test_global.c index 2eac05c..56c6317 100644 --- a/test/test/swfdec_test_global.c +++ b/test/test/swfdec_test_global.c @@ -26,4 +26,15 @@ #include "swfdec_test_function.h" #include "swfdec_test_initialize.h" +SWFDEC_TEST_FUNCTION ("print", swfdec_test_print, 0) +void +swfdec_test_print (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, + SwfdecAsValue *argv, SwfdecAsValue *retval) +{ + const char *s; + + SWFDEC_AS_CHECK (0, NULL, "s", s); + + g_print ("%s\n", s); +} diff --git a/test/test/swfdec_test_initialize.as b/test/test/swfdec_test_initialize.as index bc6e5ad..45d807b 100644 --- a/test/test/swfdec_test_initialize.as +++ b/test/test/swfdec_test_initialize.as @@ -18,3 +18,9 @@ */ Test = Native.Test; +Test.reset = Native.reset; + +print = function (s) { + if (s) + Native.print ("INFO: " + s); +}; diff --git a/test/test/swfdec_test_initialize.h b/test/test/swfdec_test_initialize.h index ea1dfde..547e492 100644 --- a/test/test/swfdec_test_initialize.h +++ b/test/test/swfdec_test_initialize.h @@ -2,8 +2,14 @@ /* compiled from swfdec_test_initialize.as */ static const unsigned char swfdec_test_initialize[] = { - 0x88, 0x0E, 0x00, 0x02, 0x00, 0x54, 0x65, 0x73, 0x74, 0x00, 0x4E, 0x61, 0x74, 0x69, 0x76, 0x65, - 0x00, 0x96, 0x04, 0x00, 0x08, 0x00, 0x08, 0x01, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x00, 0x4E, 0x1D, - 0x00 + 0x88, 0x23, 0x00, 0x06, 0x00, 0x54, 0x65, 0x73, 0x74, 0x00, 0x4E, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x00, 0x72, 0x65, 0x73, 0x65, 0x74, 0x00, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x00, 0x73, 0x00, 0x49, + 0x4E, 0x46, 0x4F, 0x3A, 0x20, 0x00, 0x96, 0x04, 0x00, 0x08, 0x00, 0x08, 0x01, 0x1C, 0x96, 0x02, + 0x00, 0x08, 0x00, 0x4E, 0x1D, 0x96, 0x02, 0x00, 0x08, 0x00, 0x1C, 0x96, 0x04, 0x00, 0x08, 0x02, + 0x08, 0x01, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x02, 0x4E, 0x4F, 0x96, 0x02, 0x00, 0x08, 0x03, 0x9B, + 0x07, 0x00, 0x00, 0x01, 0x00, 0x73, 0x00, 0x27, 0x00, 0x96, 0x02, 0x00, 0x08, 0x04, 0x1C, 0x12, + 0x9D, 0x02, 0x00, 0x1B, 0x00, 0x96, 0x04, 0x00, 0x08, 0x05, 0x08, 0x04, 0x1C, 0x47, 0x96, 0x07, + 0x00, 0x07, 0x01, 0x00, 0x00, 0x00, 0x08, 0x01, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x03, 0x52, 0x17, + 0x1D, 0x00 }; commit d72839e43e6766d1fd4636bf32417365b8eb76b6 Author: Benjamin Otte <otte at gnome.org> Date: Mon Jan 7 17:38:08 2008 +0100 add new scripted testsuite diff --git a/configure.ac b/configure.ac index c09d6cf..98d756a 100644 --- a/configure.ac +++ b/configure.ac @@ -354,6 +354,7 @@ player/Makefile test/Makefile test/image/Makefile test/sound/Makefile +test/test/Makefile test/trace/Makefile test/various/Makefile vivified/Makefile diff --git a/test/Makefile.am b/test/Makefile.am index 1aca7fa..d69a082 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = image sound trace various +SUBDIRS = image sound test trace various if WITH_GTK diff --git a/test/test/.gitignore b/test/test/.gitignore new file mode 100644 index 0000000..7bd49f0 --- /dev/null +++ b/test/test/.gitignore @@ -0,0 +1,2 @@ +compiler +test diff --git a/test/test/Makefile.am b/test/test/Makefile.am new file mode 100644 index 0000000..6bc3dac --- /dev/null +++ b/test/test/Makefile.am @@ -0,0 +1,30 @@ +check_PROGRAMS = test +TESTS = $(check_PROGRAMS) + +swfdec_test_sources = \ + swfdec_test.c \ + swfdec_test_function.c \ + swfdec_test_function.h \ + swfdec_test_test.c \ + swfdec_test_test.h + +BUILT_SOURCES = \ + swfdec_test_function_list.h + +CLEANFILES = \ + $(BUILT_SOURCES) + +test_SOURCES = \ + $(swfdec_test_sources) \ + $(BUILT_SOURCES) + +test_CFLAGS = $(GLOBAL_CFLAGS) $(GTK_CFLAGS) $(SWFDEC_CFLAGS) $(CAIRO_CFLAGS) +test_LDFLAGS = $(SWFDEC_LIBS) $(GTK_LIBS) $(CAIRO_LIBS) + +swfdec_test_function_list.h: $(swfdec_test_sources) + (cd $(srcdir) \ + && grep -he "^SWFDEC_TEST_FUNCTION" $(swfdec_test_sources) \ + ) >> xgen-sfl \ + && (cmp -s xgen-sfl swfdec_test_function_list.h || cp xgen-sfl swfdec_test_function_list.h) \ + && rm -f xgen-sfl + diff --git a/test/test/compiler.c b/test/test/compiler.c new file mode 100644 index 0000000..ce0ef12 --- /dev/null +++ b/test/test/compiler.c @@ -0,0 +1,53 @@ +//gcc -Wall -Werror `pkg-config --libs --cflags libming glib-2.0` compiler.c -o compiler + +#include <glib.h> +#include <ming.h> +#include <string.h> + +/* This is what is used to compile the Actionscript parts of the source to + * Swfdec test scripts that can later be executed. + * Note that this is pretty much a hack until someone writes a proper + * Actionscript compiler for Swfdec. + * Also note that the creation of the include-scripts should probably not be + * autorun, as we don't want to depend on external bugs in Ming, only on internal ones. + */ + +/* header to put in front of script */ +#define HEADER "Swfdec Test Script\0\1" + +int +main (int argc, char **argv) +{ + SWFAction action; + char *contents; + GError *error = NULL; + gsize len; + byte *data; + + if (argc != 3) { + g_print ("usage: %s INFILE OUTFILE\n\n", argv[0]); + return 1; + } + + Ming_init (); + + if (!g_file_get_contents (argv[1], &contents, NULL, &error)) { + g_printerr ("%s\n", error->message); + g_error_free (error); + error = NULL; + return 1; + } + action = newSWFAction (contents); + data = SWFAction_getByteCode (action, &len); + contents = g_malloc (len + sizeof (HEADER)); + memcpy (contents, HEADER, sizeof (HEADER)); + memcpy (contents + sizeof (HEADER), data, len); + if (!g_file_set_contents (argv[2], contents, len + sizeof (HEADER), &error)) { + g_printerr ("%s\n", error->message); + g_error_free (error); + error = NULL; + return 1; + } + g_free (contents); + return 0; +} diff --git a/test/test/swfdec_test.c b/test/test/swfdec_test.c new file mode 100644 index 0000000..1e65276 --- /dev/null +++ b/test/test/swfdec_test.c @@ -0,0 +1,141 @@ +/* Swfdec + * Copyright (C) 2008 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 <stdlib.h> +#include <string.h> + +#include <libswfdec/swfdec.h> +/* FIXME: no internal headers please */ +#include <libswfdec/swfdec_as_array.h> +#include <libswfdec/swfdec_as_internal.h> + +#include "swfdec_test_function.h" +#include "swfdec_test_initialize.h" + + +/* Start of script file */ +#define SWFDEC_TEST_FILE_ID "Swfdec Test Script\0\1" +/* Flash version the script engine runs in */ +#define SWFDEC_TEST_VERSION 8 + +static SwfdecScript * +load_script (const char *filename) +{ + SwfdecBuffer *file, *buffer; + SwfdecScript *script; + GError *error = NULL; + + if (filename == NULL) + filename = "default.sts"; + + file = swfdec_buffer_new_from_file (filename, &error); + if (file == NULL) { + g_print ("ERROR: %s\n", error->message); + g_error_free (error); + return NULL; + } + if (file->length < sizeof (SWFDEC_TEST_FILE_ID) + 1 || + memcmp (file->data, SWFDEC_TEST_FILE_ID, sizeof (SWFDEC_TEST_FILE_ID) != 0)) { + g_print ("ERROR: %s is not a Swfdec test script\n", filename); + swfdec_buffer_unref (file); + return NULL; + } + buffer = swfdec_buffer_new_subbuffer (file, sizeof (SWFDEC_TEST_FILE_ID), + file->length - sizeof (SWFDEC_TEST_FILE_ID)); + swfdec_buffer_unref (file); + script = swfdec_script_new (buffer, "main", SWFDEC_TEST_VERSION); + return script; +} + +int +main (int argc, char **argv) +{ + char *script_filename = NULL; + GError *error = NULL; + SwfdecAsContext *context; + SwfdecAsObject *array; + SwfdecScript *script; + SwfdecAsValue val; + int i, ret; + + GOptionEntry options[] = { + { "script", 's', 0, G_OPTION_ARG_STRING, &script_filename, "script to execute if not ./default.sts", "FILENAME" }, + { NULL } + }; + GOptionContext *ctx; + + ctx = g_option_context_new (""); + g_option_context_add_main_entries (ctx, options, "options"); + g_option_context_parse (ctx, &argc, &argv, &error); + g_option_context_free (ctx); + + if (error) { + g_printerr ("ERROR: wrong command line arguments: %s\n", error->message); + g_error_free (error); + return EXIT_FAILURE; + } + + if (argc < 2) { + g_printerr ("ERROR: Usage: %s [OPTIONS] filename\n", argv[0]); + return EXIT_FAILURE; + } + + swfdec_init (); + script = load_script (script_filename); + g_free (script_filename); + if (script == NULL) + return EXIT_FAILURE; + + context = g_object_new (SWFDEC_TYPE_AS_CONTEXT, NULL); + swfdec_as_context_startup (context, SWFDEC_TEST_VERSION); + swfdec_test_function_init_context (context); + swfdec_as_context_run_init_script (context, swfdec_test_initialize, + sizeof (swfdec_test_initialize), SWFDEC_TEST_VERSION); + + array = swfdec_as_array_new (context); + if (array == NULL) { + g_print ("ERROR: Not enough memory"); + return EXIT_FAILURE; + } + for (i = 1; i < argc; i++) { + SWFDEC_AS_VALUE_SET_STRING (&val, swfdec_as_context_get_string (context, argv[i])); + swfdec_as_array_push (SWFDEC_AS_ARRAY (array), &val); + } + SWFDEC_AS_VALUE_SET_OBJECT (&val, array); + swfdec_as_object_set_variable (context->global, + swfdec_as_context_get_string (context, "filenames"), &val); + swfdec_as_object_run (context->global, script); + if (swfdec_as_context_catch (context, &val)) { + g_print ("ERROR: %s\n", swfdec_as_value_to_string (context, &val)); + ret = EXIT_FAILURE; + } else { + g_print ("SUCCESS\n"); + ret = EXIT_SUCCESS; + } + + swfdec_script_unref (script); + g_object_unref (context); + + return ret; +} + diff --git a/test/test/swfdec_test_function.c b/test/test/swfdec_test_function.c new file mode 100644 index 0000000..0109582 --- /dev/null +++ b/test/test/swfdec_test_function.c @@ -0,0 +1,67 @@ +/* SwfdecTestfied + * 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_test_function.h" +#include "swfdec_test_function_list.h" + +/* needed by the function list */ +#include "swfdec_test_test.h" + + +/* include swfdec_test_function_list with special macro definition, so we get a nice + * way to initialize it */ +#undef SWFDEC_TEST_FUNCTION +#define SWFDEC_TEST_FUNCTION(name, fun, type) \ + { name, fun, type }, +static const struct { + const char * name; + SwfdecAsNative fun; + GType (* type) (void); +} functions[] = { +#include "swfdec_test_function_list.h" + { NULL, NULL, NULL } +}; +#undef SWFDEC_TEST_FUNCTION + +void +swfdec_test_function_init_context (SwfdecAsContext *cx) +{ + SwfdecAsObject *obj; + SwfdecAsValue val; + guint i; + + obj = swfdec_as_object_new (cx); + if (obj == NULL) + return; + SWFDEC_AS_VALUE_SET_OBJECT (&val, obj); + swfdec_as_object_set_variable (cx->global, + swfdec_as_context_get_string (cx, "Native"), &val); + + for (i = 0; functions[i].name; i++) { + GType type = functions[i].type ? functions[i].type () : 0; + swfdec_as_object_add_constructor (obj, + swfdec_as_context_get_string (cx, functions[i].name), + type, type, functions[i].fun, 0, NULL); + } +} + diff --git a/test/test/swfdec_test_function.h b/test/test/swfdec_test_function.h new file mode 100644 index 0000000..08b6c27 --- /dev/null +++ b/test/test/swfdec_test_function.h @@ -0,0 +1,35 @@ +/* SwfdecTestfied + * 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 + */ + +#include <libswfdec/swfdec.h> + +#ifndef _SWFDEC_TEST_FUNCTION_H_ +#define _SWFDEC_TEST_FUNCTION_H_ + +G_BEGIN_DECLS + + +#define SWFDEC_TEST_FUNCTION(name, fun, type) \ + void fun (SwfdecAsContext *cx, SwfdecAsObject *this, guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval); + +void swfdec_test_function_init_context (SwfdecAsContext *cx); + + +G_END_DECLS +#endif diff --git a/test/test/swfdec_test_function_list.h b/test/test/swfdec_test_function_list.h new file mode 100644 index 0000000..46908ab --- /dev/null +++ b/test/test/swfdec_test_function_list.h @@ -0,0 +1,3 @@ +SWFDEC_TEST_FUNCTION ("Test_advance", swfdec_test_test_advance, 0) +SWFDEC_TEST_FUNCTION ("Test_reset", swfdec_test_test_reset, 0) +SWFDEC_TEST_FUNCTION ("Test", swfdec_test_test_new, swfdec_test_test_get_type) diff --git a/test/test/swfdec_test_global.c b/test/test/swfdec_test_global.c new file mode 100644 index 0000000..2eac05c --- /dev/null +++ b/test/test/swfdec_test_global.c @@ -0,0 +1,29 @@ +/* Swfdec + * Copyright (C) 2008 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 <libswfdec/swfdec.h> + +#include "swfdec_test_function.h" +#include "swfdec_test_initialize.h" + + diff --git a/test/test/swfdec_test_initialize.as b/test/test/swfdec_test_initialize.as new file mode 100644 index 0000000..bc6e5ad --- /dev/null +++ b/test/test/swfdec_test_initialize.as @@ -0,0 +1,20 @@ +/* Swfdec + * Copyright (C) 2008 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 + */ + +Test = Native.Test; diff --git a/test/test/swfdec_test_initialize.h b/test/test/swfdec_test_initialize.h new file mode 100644 index 0000000..ea1dfde --- /dev/null +++ b/test/test/swfdec_test_initialize.h @@ -0,0 +1,9 @@ +/* This file is autogenerated, do not edit! */ + +/* compiled from swfdec_test_initialize.as */ +static const unsigned char swfdec_test_initialize[] = { + 0x88, 0x0E, 0x00, 0x02, 0x00, 0x54, 0x65, 0x73, 0x74, 0x00, 0x4E, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x00, 0x96, 0x04, 0x00, 0x08, 0x00, 0x08, 0x01, 0x1C, 0x96, 0x02, 0x00, 0x08, 0x00, 0x4E, 0x1D, + 0x00 +}; + diff --git a/test/test/swfdec_test_test.c b/test/test/swfdec_test_test.c new file mode 100644 index 0000000..74473ee --- /dev/null +++ b/test/test/swfdec_test_test.c @@ -0,0 +1,157 @@ +/* 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_test_test.h" +#include "swfdec_test_function.h" + +/*** trace capturing ***/ + + + +/*** SWFDEC_TEST_TEST ***/ + +G_DEFINE_TYPE (SwfdecTestTest, swfdec_test_test, SWFDEC_TYPE_AS_OBJECT) + +static void +swfdec_test_test_dispose (GObject *object) +{ + SwfdecTestTest *test = SWFDEC_TEST_TEST (object); + + g_free (test->filename); + test->filename = NULL; + if (test->player) { + g_object_unref (test->player); + test->player = NULL; + } + + G_OBJECT_CLASS (swfdec_test_test_parent_class)->dispose (object); +} + +static void +swfdec_test_test_class_init (SwfdecTestTestClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = swfdec_test_test_dispose; +} + +static void +swfdec_test_test_init (SwfdecTestTest *this) +{ +} + +#if 0 +static void +swfdec_test_throw (SwfdecAsContext *cx, const char *error) +{ + SwfdecAsValue val; + + if (!swfdec_as_context_catch (cx, &val)) { + /* FIXME: Throw a real object here? */ + SWFDEC_AS_VALUE_SET_STRING (&val, swfdec_as_context_get_string (cx, error)); + } + swfdec_as_context_throw (cx, &val); +} +#endif + +static void +swfdec_test_test_fscommand (SwfdecPlayer *player, const char *command, + const char *para, SwfdecTestTest *test) +{ + if (g_ascii_strcasecmp (command, "quit")) { + test->player_quit = TRUE; + } +} + +static gboolean +swfdec_test_test_ensure_player (SwfdecTestTest *test) +{ + if (test->filename == NULL) + return FALSE; + + test->player = swfdec_player_new_from_file (test->filename); + g_signal_connect (test, "fscommand", G_CALLBACK (swfdec_test_test_fscommand), test); + return TRUE; +} + +static void +swfdec_test_do_reset (SwfdecTestTest *test, const char *filename) +{ + if (test->player) { + g_object_unref (test->player); + test->player = NULL; + } + if (filename == NULL) + return; + + test->filename = g_strdup (filename); +} + +SWFDEC_TEST_FUNCTION ("Test_advance", swfdec_test_test_advance, 0) +void +swfdec_test_test_advance (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, + SwfdecAsValue *argv, SwfdecAsValue *retval) +{ + SwfdecTestTest *test; + int msecs; + + SWFDEC_AS_CHECK (SWFDEC_TYPE_TEST_TEST, &test, "i", &msecs); + + if (msecs <= 0 || test->player_quit) + return; + swfdec_test_test_ensure_player (test); + while (msecs > 0 && !test->player_quit) { + int next_event = swfdec_player_get_next_event (test->player); + if (next_event < 0) + break; + next_event = MIN (next_event, msecs); + swfdec_player_advance (test->player, next_event); + msecs -= next_event; + } +} + +SWFDEC_TEST_FUNCTION ("Test_reset", swfdec_test_test_reset, 0) +void +swfdec_test_test_reset (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, + SwfdecAsValue *argv, SwfdecAsValue *retval) +{ + SwfdecTestTest *test; + const char *filename; + + SWFDEC_AS_CHECK (SWFDEC_TYPE_TEST_TEST, &test, "|s", &filename); + + swfdec_test_do_reset (test, filename); +} + +SWFDEC_TEST_FUNCTION ("Test", swfdec_test_test_new, swfdec_test_test_get_type) +void +swfdec_test_test_new (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, + SwfdecAsValue *argv, SwfdecAsValue *retval) +{ + SwfdecTestTest *test; + const char *filename; + + SWFDEC_AS_CHECK (SWFDEC_TYPE_TEST_TEST, &test, "|s", &filename); + + swfdec_test_do_reset (test, filename); +} diff --git a/test/test/swfdec_test_test.h b/test/test/swfdec_test_test.h new file mode 100644 index 0000000..7172897 --- /dev/null +++ b/test/test/swfdec_test_test.h @@ -0,0 +1,56 @@ +/* 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_TEST_TEST_H_ +#define _SWFDEC_TEST_TEST_H_ + +#include <libswfdec/swfdec.h> + +G_BEGIN_DECLS + + +typedef struct _SwfdecTestTest SwfdecTestTest; +typedef struct _SwfdecTestTestClass SwfdecTestTestClass; + +#define SWFDEC_TYPE_TEST_TEST (swfdec_test_test_get_type()) +#define SWFDEC_IS_TEST_TEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_TEST_TEST)) +#define SWFDEC_IS_TEST_TEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_TEST_TEST)) +#define SWFDEC_TEST_TEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_TEST_TEST, SwfdecTestTest)) +#define SWFDEC_TEST_TEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_TEST_TEST, SwfdecTestTestClass)) +#define SWFDEC_TEST_TEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_TEST_TEST, SwfdecTestTestClass)) + +struct _SwfdecTestTest +{ + SwfdecAsObject as_object; + + char * filename; /* file the player should be loaded from */ + SwfdecPlayer * player; /* the player or %NULL if none */ + gboolean player_quit; /* the player has called fscommand:quit */ +}; + +struct _SwfdecTestTestClass +{ + SwfdecAsObjectClass as_object_class; +}; + +GType swfdec_test_test_get_type (void); + + +G_END_DECLS +#endif commit 97d89d8dc0605f5d42c4bf56039822c22e2eaaa8 Author: Benjamin Otte <otte at gnome.org> Date: Mon Jan 7 17:20:52 2008 +0100 fix typo diff --git a/vivified/core/Makefile.am b/vivified/core/Makefile.am index 1252f5a..5e274f1 100644 --- a/vivified/core/Makefile.am +++ b/vivified/core/Makefile.am @@ -50,7 +50,7 @@ vivi_function_list.h: $(libvivified_core_source) (cd $(srcdir) \ && grep -he "^VIVI_FUNCTION" $(libvivified_core_sources) \ ) >> xgen-vfl \ - && (cmp -s xgen-vfl vivi_asnative.h || cp xgen-vfl vivi_function_list.h) \ + && (cmp -s xgen-vfl vivi_function_list.h || cp xgen-vfl vivi_function_list.h) \ && rm -f xgen-vfl vivi_marshal.h: vivi_marshal.list Makefile
Reasonably Related Threads
- 9 commits - libswfdec/js libswfdec/swfdec_bits.c libswfdec/swfdec_bits.h libswfdec/swfdec_codec_screen.c libswfdec/swfdec_image.c libswfdec/swfdec_script.c test/Makefile.am test/swfdec_out.c test/swfdec_out.h test/swfedit.c test/swfedit_file.c
- 7 commits - libswfdec/swfdec_image.c libswfdec/swfdec_script.c libswfdec/swfdec_script.h test/Makefile.am test/swfdec_out.c test/swfdec_out.h test/swfedit.c test/swfedit_list.c test/swfedit_tag.c test/swfedit_token.c test/swfedit_token.h test/swfscript.c
- Branch 'interpreter' - 28 commits - configure.ac libswfdec/js libswfdec/swfdec_buffer.c libswfdec/swfdec_edittext_movie.c libswfdec/swfdec_js.c libswfdec/swfdec_js_global.c libswfdec/swfdec_js.h libswfdec/swfdec_js_movie.c libswfdec/swfdec_player.c
- Branch 'interpreter' - 8 commits - libswfdec/swfdec_bits.c libswfdec/swfdec_color.c libswfdec/swfdec_color.h libswfdec/swfdec_edittext.c libswfdec/swfdec_image.c libswfdec/swfdec_image.h libswfdec/swfdec_pattern.c libswfdec/swfdec_sprite.c test/dump.c
- 109 commits - configure.ac libswfdec/js libswfdec/Makefile.am libswfdec/swfdec_bits.c libswfdec/swfdec_bits.h libswfdec/swfdec_buffer.c libswfdec/swfdec_button_movie.c libswfdec/swfdec_codec_screen.c libswfdec/swfdec_color.c libswfdec/swfdec_color.h