⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 swfdec_tag.c

📁 Swfdec is a decoder/renderer for Macromedia Flash animations. The decoding and rendering engine is
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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 + -