📄 swfdec_tag.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 <zlib.h>#include <math.h>#include <string.h>#include <stdlib.h>#include "swfdec_tag.h"#include "swfdec_bits.h"#include "swfdec_button.h"#include "swfdec_debug.h"#include "swfdec_edittext.h"#include "swfdec_font.h"#include "swfdec_image.h"#include "swfdec_morphshape.h"#include "swfdec_movie.h" /* for SwfdecContent */#include "swfdec_pattern.h"#include "swfdec_player_internal.h"#include "swfdec_script_internal.h"#include "swfdec_shape.h"#include "swfdec_sound.h"#include "swfdec_sprite.h"#include "swfdec_text.h"#include "swfdec_video.h"static inttag_func_end (SwfdecSwfDecoder * s, guint tag){ return SWFDEC_STATUS_OK;}static inttag_func_protect (SwfdecSwfDecoder * s, guint tag){ if (s->protection) { SWFDEC_INFO ("This file is really protected."); g_free (s->password); s->password = NULL; } s->protection = TRUE; if (swfdec_bits_left (&s->b)) { /* FIXME: What's this for? */ swfdec_bits_get_u16 (&s->b); s->password = swfdec_bits_get_string (&s->b); } return SWFDEC_STATUS_OK;}static inttag_func_frame_label (SwfdecSwfDecoder * s, guint tag){ SwfdecSpriteFrame *frame = &s->parse_sprite->frames[s->parse_sprite->parse_frame]; if (frame->label) { SWFDEC_WARNING ("frame %d already has a label (%s)", s->parse_sprite->parse_frame, frame->label); g_free (frame->label); } frame->label = swfdec_bits_get_string (&s->b); SWFDEC_LOG ("frame %d named %s", s->parse_sprite->parse_frame, frame->label); return SWFDEC_STATUS_OK;}/* text */inttag_func_define_text (SwfdecSwfDecoder * s, guint tag){ SwfdecBits *bits = &s->b; int id; int n_glyph_bits; int n_advance_bits; SwfdecText *text = NULL; SwfdecTextGlyph glyph = { 0 }; id = swfdec_bits_get_u16 (bits); text = swfdec_swf_decoder_create_character (s, id, SWFDEC_TYPE_TEXT); if (!text) return SWFDEC_STATUS_OK; glyph.color = 0xffffffff; swfdec_bits_get_rect (bits, &SWFDEC_GRAPHIC (text)->extents); swfdec_bits_get_matrix (bits, &text->transform, &text->transform_inverse); swfdec_bits_syncbits (bits); n_glyph_bits = swfdec_bits_get_u8 (bits); n_advance_bits = swfdec_bits_get_u8 (bits); //printf(" n_glyph_bits = %d\n", n_glyph_bits); //printf(" n_advance_bits = %d\n", n_advance_bits); while (swfdec_bits_peekbits (bits, 8) != 0) { int type; type = swfdec_bits_getbit (bits); if (type == 0) { /* glyph record */ int n_glyphs; int i; n_glyphs = swfdec_bits_getbits (bits, 7); if (glyph.font == NULL) SWFDEC_ERROR ("no font for %d glyphs", n_glyphs); for (i = 0; i < n_glyphs; i++) { glyph.glyph = swfdec_bits_getbits (bits, n_glyph_bits); if (glyph.font != NULL) g_array_append_val (text->glyphs, glyph); glyph.x += swfdec_bits_getsbits (bits, n_advance_bits); } } else { /* state change */ int reserved; int has_font; int has_color; int has_y_offset; int has_x_offset; reserved = swfdec_bits_getbits (bits, 3); has_font = swfdec_bits_getbit (bits); has_color = swfdec_bits_getbit (bits); has_y_offset = swfdec_bits_getbit (bits); has_x_offset = swfdec_bits_getbit (bits); if (has_font) { glyph.font = swfdec_swf_decoder_get_character (s, swfdec_bits_get_u16 (bits)); //printf(" font = %d\n",font); } if (has_color) { if (tag == SWFDEC_TAG_DEFINETEXT) { glyph.color = swfdec_bits_get_color (bits); } else { glyph.color = swfdec_bits_get_rgba (bits); } //printf(" color = %08x\n",glyph.color); } if (has_x_offset) { glyph.x = swfdec_bits_get_s16 (bits); } if (has_y_offset) { glyph.y = swfdec_bits_get_s16 (bits); } if (has_font) { glyph.height = swfdec_bits_get_u16 (bits); } } swfdec_bits_syncbits (bits); } swfdec_bits_get_u8 (bits); return SWFDEC_STATUS_OK;}inttag_func_define_sprite (SwfdecSwfDecoder * s, guint define_sprite_tag){ SwfdecBits parse; int id; SwfdecSprite *sprite; int ret; guint tag = 1; parse = s->b; id = swfdec_bits_get_u16 (&parse); sprite = swfdec_swf_decoder_create_character (s, id, SWFDEC_TYPE_SPRITE); if (!sprite) return SWFDEC_STATUS_OK; SWFDEC_LOG (" ID: %d", id); swfdec_sprite_set_n_frames (sprite, swfdec_bits_get_u16 (&parse), SWFDEC_DECODER (s)->rate); s->parse_sprite = sprite; while (swfdec_bits_left (&parse)) { int x; guint tag_len; SwfdecTagFunc func; x = swfdec_bits_get_u16 (&parse); tag = (x >> 6) & 0x3ff; tag_len = x & 0x3f; if (tag_len == 0x3f) { tag_len = swfdec_bits_get_u32 (&parse); } SWFDEC_INFO ("sprite parsing at %td, tag %d %s, length %d", parse.buffer ? parse.ptr - parse.buffer->data : 0, tag, swfdec_swf_decoder_get_tag_name (tag), tag_len); if (tag_len == 0) { swfdec_bits_init_data (&s->b, NULL, 0); } else { swfdec_bits_init_bits (&s->b, &parse, tag_len); } func = swfdec_swf_decoder_get_tag_func (tag); if (tag == 0) { break; } else if (func == NULL) { SWFDEC_WARNING ("tag function not implemented for %d %s", tag, swfdec_swf_decoder_get_tag_name (tag)); } else if ((swfdec_swf_decoder_get_tag_flag (tag) & 1) == 0) { SWFDEC_ERROR ("invalid tag %d %s during DefineSprite", tag, swfdec_swf_decoder_get_tag_name (tag)); } else if (s->parse_sprite->parse_frame < s->parse_sprite->n_frames) { ret = func (s, tag); if (swfdec_bits_left (&s->b)) { SWFDEC_WARNING ("early parse finish (%d bytes)", swfdec_bits_left (&s->b) / 8); } } else { SWFDEC_ERROR ("data after last frame"); } } /* sanity check the sprite */ if (s->parse_sprite->n_frames != s->parse_sprite->parse_frame) { SWFDEC_INFO ("not enough frames in sprite %u (have %u, want %u), filling up with empty frames", id, s->parse_sprite->parse_frame, s->parse_sprite->n_frames); s->parse_sprite->parse_frame = s->parse_sprite->n_frames; } s->b = parse; /* this assumes that no recursive DefineSprite happens and we check it doesn't */ s->parse_sprite = s->main_sprite; SWFDEC_LOG ("done parsing this sprite"); return SWFDEC_STATUS_OK;}voidswfdec_filters_parse (SwfdecBits *bits){ guint i, n_filters, filter_id; n_filters = swfdec_bits_get_u8 (bits); SWFDEC_WARNING (" filters: %u", n_filters); for (i = 0; i < n_filters && swfdec_bits_left (bits); i++) { filter_id = swfdec_bits_get_u8 (bits); switch (filter_id) { case 0: SWFDEC_WARNING (" drop shadow"); swfdec_bits_skip_bytes (bits, 16); break; case 1: SWFDEC_WARNING (" blur"); swfdec_bits_skip_bytes (bits, 9); break; case 2: SWFDEC_WARNING (" glow"); swfdec_bits_skip_bytes (bits, 15); break; case 3: SWFDEC_WARNING (" bevel"); swfdec_bits_skip_bytes (bits, 27); break; case 4: { guint n; n = swfdec_bits_get_u8 (bits); SWFDEC_WARNING (" gradient glow"); swfdec_bits_skip_bytes (bits, n * 5 + 19); } break; case 5: { guint x, y; x = swfdec_bits_get_u8 (bits); y = swfdec_bits_get_u8 (bits); SWFDEC_WARNING (" %u x %u convolution", x, y); swfdec_bits_skip_bytes (bits, (x + y) * 4 + 13); } break; case 6: SWFDEC_WARNING (" color matrix"); swfdec_bits_skip_bytes (bits, 20 * 4); break; case 7: { guint n; n = swfdec_bits_get_u8 (bits); SWFDEC_WARNING (" gradient bevel"); swfdec_bits_skip_bytes (bits, n * 5 + 19); } break; default: SWFDEC_ERROR ("unknown filter id %u", filter_id); break; } }}#define CONTENT_IN_FRAME(content, frame) \ ((content)->sequence->start <= frame && \ (content)->sequence->end > frame)static guintswfdec_button_remove_duplicates (SwfdecButton *button, int depth, guint states){ GList *walk; guint taken = 0; guint i; /* 1) find out which states are already taken */ for (walk = button->records; walk; walk = walk->next) { SwfdecContent *cur = walk->data; if (cur->depth != depth) continue; for (i = 0; i < 4; i++) { if (CONTENT_IN_FRAME (cur, i)) taken |= (1 << i); } } /* 2) mark states that overlap */ taken &= states; /* 3) remove the overlapping states */ if (taken) { SWFDEC_ERROR ("overlapping contents in button, removing for depth %u and states %u", depth, taken); states &= ~taken; } return states;}static voidswfdec_button_append_content (SwfdecButton *button, guint states, SwfdecContent *content){ guint i; SwfdecContent *cur = NULL; states = swfdec_button_remove_duplicates (button, content->depth, states); for (i = 0; i < 4; i++) { if (!cur && (states & 1)) { cur = content; if (content->end != G_MAXUINT) { /* need a copy here */ cur = swfdec_content_new (content->depth); *cur = *content; cur->sequence = cur; } cur->start = i; button->records = g_list_append (button->records, cur); } if (cur && !(states & 1)) { cur->end = i; cur = NULL; } states >>= 1; } if (cur) { SwfdecRect rect; cur->end = 4; swfdec_rect_transform (&rect, &content->graphic->extents, &cur->transform); swfdec_rect_union (&SWFDEC_GRAPHIC (button)->extents, &SWFDEC_GRAPHIC (button)->extents, &rect); } if (content->end == G_MAXUINT) { SWFDEC_ERROR ("button record for graphic %u is not used in any state, discarding", SWFDEC_CHARACTER (content->graphic)->id); swfdec_content_free (content); }}static inttag_func_define_button_2 (SwfdecSwfDecoder * s, guint tag){ SwfdecBits bits; int id, reserved; guint length; SwfdecButton *button; char *script_name; id = swfdec_bits_get_u16 (&s->b); button = swfdec_swf_decoder_create_character (s, id, SWFDEC_TYPE_BUTTON); if (!button) return SWFDEC_STATUS_OK; SWFDEC_LOG (" ID: %d", id); reserved = swfdec_bits_getbits (&s->b, 7); button->menubutton = swfdec_bits_getbit (&s->b) ? TRUE : FALSE; length = swfdec_bits_get_u16 (&s->b); SWFDEC_LOG (" reserved = %d", reserved); SWFDEC_LOG (" menu = %d", button->menubutton);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -