📄 swfdec_sprite.c
字号:
/* Swfdec * Copyright (C) 2003-2006 David Schleef <ds@schleef.org> * 2005-2006 Eric Anholt <eric@anholt.net> * 2006-2007 Benjamin Otte <otte@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_sprite.h"#include "swfdec_debug.h"#include "swfdec_movie.h"#include "swfdec_player_internal.h"#include "swfdec_script.h"#include "swfdec_sound.h"#include "swfdec_sprite_movie.h"#include "swfdec_swf_decoder.h"G_DEFINE_TYPE (SwfdecSprite, swfdec_sprite, SWFDEC_TYPE_GRAPHIC)voidswfdec_content_free (SwfdecContent *content){ g_free (content->name); if (content->events) swfdec_event_list_free (content->events); g_free (content);}static voidswfdec_sprite_dispose (GObject *object){ SwfdecSprite * sprite = SWFDEC_SPRITE (object); unsigned int i; if (sprite->live_content) { g_hash_table_destroy (sprite->live_content); sprite->live_content = NULL; } if (sprite->frames) { for (i = 0; i < sprite->n_frames; i++) { g_free (sprite->frames[i].label); if (sprite->frames[i].sound_head) g_object_unref (sprite->frames[i].sound_head); if (sprite->frames[i].sound_block) { swfdec_buffer_unref (sprite->frames[i].sound_block); } if (sprite->frames[i].actions) { guint j; for (j = 0; j < sprite->frames[i].actions->len; j++) { SwfdecSpriteAction *action = &g_array_index (sprite->frames[i].actions, SwfdecSpriteAction, j); switch (action->type) { case SWFDEC_SPRITE_ACTION_SCRIPT: swfdec_script_unref (action->data); break; case SWFDEC_SPRITE_ACTION_ADD: case SWFDEC_SPRITE_ACTION_UPDATE: swfdec_content_free (action->data); break; case SWFDEC_SPRITE_ACTION_REMOVE: break; default: g_assert_not_reached (); } } g_array_free (sprite->frames[i].actions, TRUE); } g_slist_foreach (sprite->frames[i].sound, (GFunc) swfdec_sound_chunk_free, NULL); g_slist_free (sprite->frames[i].sound); } g_free(sprite->frames); } if (sprite->init_action) { swfdec_script_unref (sprite->init_action); sprite->init_action = NULL; } G_OBJECT_CLASS (swfdec_sprite_parent_class)->dispose (object);}voidswfdec_sprite_add_sound_chunk (SwfdecSprite * sprite, unsigned int frame, SwfdecBuffer * chunk, int skip, guint n_samples){ g_assert (sprite->frames != NULL); g_assert (chunk != NULL || n_samples == 0); if (sprite->frames[frame].sound_head == NULL) { SWFDEC_ERROR ("attempting to add a sound block without previous sound head"); swfdec_buffer_unref (chunk); return; } if (sprite->frames[frame].sound_block) { SWFDEC_ERROR ("attempting to add 2 sound blocks to one frame"); swfdec_buffer_unref (chunk); return; } SWFDEC_LOG ("adding %u samples in %u bytes to frame %u", n_samples, chunk ? chunk->length : 0, frame); sprite->frames[frame].sound_skip = skip; sprite->frames[frame].sound_block = chunk; sprite->frames[frame].sound_samples = n_samples * SWFDEC_AUDIO_OUT_GRANULARITY (sprite->frames[frame].sound_head->original_format);}/* find the last action in this depth if it exists *//* NB: we look in the current frame, too - so call this before adding actions * that might modify the frame you're looking for */static SwfdecContent *swfdec_content_find (SwfdecSprite *sprite, int depth){ return g_hash_table_lookup (sprite->live_content, GINT_TO_POINTER (depth));}static voidswfdec_content_update_lifetime (SwfdecSprite *sprite, SwfdecSpriteActionType type, gpointer data){ SwfdecContent *content; int depth; switch (type) { case SWFDEC_SPRITE_ACTION_SCRIPT: case SWFDEC_SPRITE_ACTION_UPDATE: return; case SWFDEC_SPRITE_ACTION_ADD: depth = ((SwfdecContent *) data)->depth; break; case SWFDEC_SPRITE_ACTION_REMOVE: depth = GPOINTER_TO_INT (data); break; default: g_assert_not_reached (); return; } content = swfdec_content_find (sprite, depth); if (content == NULL) return; content->sequence->end = sprite->parse_frame;}static voidswfdec_content_update_live (SwfdecSprite *sprite, SwfdecSpriteActionType type, gpointer data){ SwfdecContent *content; switch (type) { case SWFDEC_SPRITE_ACTION_SCRIPT: return; case SWFDEC_SPRITE_ACTION_UPDATE: case SWFDEC_SPRITE_ACTION_ADD: content = data; g_hash_table_insert (sprite->live_content, GINT_TO_POINTER (content->depth), content); break; case SWFDEC_SPRITE_ACTION_REMOVE: /* data is GINT_TO_POINTER (depth) */ g_hash_table_remove (sprite->live_content, data); break; default: g_assert_not_reached (); return; }}/* NB: does not free the action data */static voidswfdec_sprite_remove_last_action (SwfdecSprite * sprite, unsigned int frame_id){ SwfdecSpriteFrame *frame; g_assert (frame_id < sprite->n_frames); frame = &sprite->frames[frame_id]; g_assert (frame->actions != NULL); g_assert (frame->actions->len > 0); g_array_set_size (frame->actions, frame->actions->len - 1);}voidswfdec_sprite_add_action (SwfdecSprite *sprite, SwfdecSpriteActionType type, gpointer data){ SwfdecSpriteAction action; SwfdecSpriteFrame *frame; g_assert (sprite->parse_frame < sprite->n_frames); frame = &sprite->frames[sprite->parse_frame]; if (frame->actions == NULL) frame->actions = g_array_new (FALSE, FALSE, sizeof (SwfdecSpriteAction)); swfdec_content_update_lifetime (sprite, type, data); swfdec_content_update_live (sprite, type, data); action.type = type; action.data = data; g_array_append_val (frame->actions, action);}static intswfdec_get_clipeventflags (SwfdecSwfDecoder * s, SwfdecBits * bits){ if (s->version <= 5) { return swfdec_bits_get_u16 (bits); } else { return swfdec_bits_get_u32 (bits); }}inttag_show_frame (SwfdecSwfDecoder * s){ SWFDEC_DEBUG("show_frame %d of id %d", s->parse_sprite->parse_frame, SWFDEC_CHARACTER (s->parse_sprite)->id); s->parse_sprite->parse_frame++; if (s->parse_sprite->parse_frame < s->parse_sprite->n_frames) { SwfdecSpriteFrame *old = &s->parse_sprite->frames[s->parse_sprite->parse_frame - 1]; SwfdecSpriteFrame *new = &s->parse_sprite->frames[s->parse_sprite->parse_frame]; if (old->sound_head) new->sound_head = g_object_ref (old->sound_head); } return SWFDEC_STATUS_IMAGE;}inttag_func_set_background_color (SwfdecSwfDecoder * s){ SwfdecPlayer *player = SWFDEC_DECODER (s)->player; SwfdecColor color = swfdec_bits_get_color (&s->b); if (player->bgcolor_set) { /* only an INFO because it can be set by user, should be error if we check duplication of tag */ SWFDEC_INFO ("background color has been set to %X already, setting to %X ignored", player->bgcolor, color); } else { SWFDEC_LOG ("setting background color to %X", color); /* can't use swfdec_player_set_background_color() here, because the player is locked and doesn't emit signals */ player->bgcolor = color; player->bgcolor_set = TRUE; player->invalid.x0 = SWFDEC_DOUBLE_TO_TWIPS (0.0); player->invalid.y0 = SWFDEC_DOUBLE_TO_TWIPS (0.0); player->invalid.x1 = SWFDEC_DOUBLE_TO_TWIPS (player->width); player->invalid.y1 = SWFDEC_DOUBLE_TO_TWIPS (player->height); g_object_notify (G_OBJECT (player), "background-color"); } return SWFDEC_STATUS_OK;}SwfdecContent *swfdec_content_new (int depth){ SwfdecContent *content = g_new0 (SwfdecContent, 1); cairo_matrix_init_identity (&content->transform); swfdec_color_transform_init_identity (&content->color_transform); content->depth = depth; content->sequence = content; content->end = G_MAXUINT; return content;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -