📄 swfdec_sprite.c
字号:
#include "swfdec_internal.h"SwfdecSprite *swfdec_sprite_new(void){ SwfdecSprite *sprite; sprite = g_new0(SwfdecSprite,1); return sprite;}void swfdec_sprite_decoder_free(SwfdecObject *object){ SwfdecDecoder *s = object->priv; swfdec_sprite_free(s->main_sprite); swfdec_render_free(s->render); g_free(s);}void swfdec_sprite_free(SwfdecSprite *sprite){ GList *g; for(g=g_list_first(sprite->layers);g;g=g_list_next(g)){ g_free(g->data); } g_list_free(sprite->layers); g_free(sprite);}SwfdecLayer *swfdec_sprite_prerender(SwfdecDecoder *s,SwfdecSpriteSeg *seg, SwfdecObject *object, SwfdecLayer *oldlayer){ SwfdecLayer *layer; SwfdecLayer *child_layer; SwfdecLayer *old_child_layer; GList *g; SwfdecDecoder *child_decoder = object->priv; SwfdecSprite *sprite = child_decoder->main_sprite; SwfdecSpriteSeg *tmpseg; SwfdecSpriteSeg *child_seg; int frame; if(oldlayer && oldlayer->seg == seg && sprite->n_frames==1)return oldlayer; layer = swfdec_layer_new(); layer->seg = seg; /* Not sure why this is wrong. Somehow the top-level transform * gets applied twice. */ //art_affine_multiply(layer->transform, seg->transform, s->transform); art_affine_copy(layer->transform, seg->transform); if(oldlayer){ layer->frame_number = oldlayer->frame_number + 1; if(layer->frame_number >= sprite->n_frames)layer->frame_number = 0; SWF_DEBUG(0,"iterating old sprite (depth=%d) old_frame=%d frame=%d n_frames=%d\n", seg->depth, oldlayer->frame_number, layer->frame_number, sprite->n_frames); }else{ SWF_DEBUG(0,"iterating new sprite (depth=%d)\n", seg->depth); layer->frame_number = 0; } frame = layer->frame_number; layer->rect.x0 = 0; layer->rect.x1 = 0; layer->rect.y0 = 0; layer->rect.y1 = 0; SWF_DEBUG(0,"swfdec_sprite_prerender %d frame %d\n",object->id,layer->frame_number); for(g=g_list_last(sprite->layers); g; g=g_list_previous(g)){ child_seg = (SwfdecSpriteSeg *)g->data; if(child_seg->first_frame > frame)continue; if(child_seg->last_frame <= frame)continue; SWF_DEBUG(0,"prerendering layer %d\n",child_seg->depth); tmpseg = swfdec_spriteseg_dup(child_seg); art_affine_multiply(tmpseg->transform, child_seg->transform, layer->transform);#if 0 old_child_layer = swfdec_render_get_sublayer(layer, child_seg->depth,layer->frame_number - 1);#endif old_child_layer = NULL; child_layer = swfdec_spriteseg_prerender(s, tmpseg, old_child_layer); if(child_layer){ layer->sublayers = g_list_append(layer->sublayers, child_layer); art_irect_union_to_masked(&layer->rect, &child_layer->rect, &s->irect); } swfdec_spriteseg_free(tmpseg); } return layer;}#if 0void swfdec_sprite_render(SwfdecDecoder *s, SwfdecLayer *parent_layer, SwfdecObject *parent_object){ SwfdecLayer *layer; SwfdecDecoder *s2 = parent_object->priv; SwfdecSprite *sprite = s2->main_sprite; GList *g; SwfdecObject *object; double save_trans[6]; SWF_DEBUG(0,"rendering sprite frame %d of %d\n", parent_layer->frame_number,s2->n_frames); for(g=g_list_last(sprite->layers); g; g=g_list_previous(g)){ layer = (SwfdecLayer *)g->data; if(layer->first_frame > parent_layer->frame_number)continue; if(layer->last_frame <= parent_layer->frame_number)continue; art_affine_copy(save_trans, layer->transform); art_affine_multiply(layer->transform, s2->transform, layer->transform); swfdec_layer_prerender(s,layer); art_affine_copy(layer->transform, save_trans); object = swfdec_object_get(s,layer->id); if(!object){ /* WTF! */ SWF_DEBUG(4,"lost object!\n"); continue; } SWF_DEBUG(0,"rendering layer %d (id = %d, type = %d)\n",layer->depth,layer->id,object->type); switch(object->type){ case SWF_OBJECT_SPRITE: swfdec_sprite_render(s,layer,object); break; case SWF_OBJECT_TEXT: swfdec_text_render(s,layer,object); break; case SWF_OBJECT_SHAPE: swfdec_shape_render(s,layer,object); break; case SWF_OBJECT_BUTTON: swfdec_button_render(s,layer,object); break; default: SWF_DEBUG(4,"render_sprite: unknown object type %d\n",object->type); break; } }}#endifvoid swfdec_sprite_render(SwfdecDecoder *s, SwfdecLayer *parent_layer, SwfdecObject *parent_object){ SwfdecLayer *child_layer; SwfdecDecoder *s2 = parent_object->priv; GList *g; SWF_DEBUG(0,"rendering sprite frame %d of %d\n", parent_layer->frame_number,s2->n_frames); for(g=g_list_first(parent_layer->sublayers); g; g=g_list_next(g)){ child_layer = (SwfdecLayer *)g->data; if(!child_layer)continue; swfdec_layer_render(s,child_layer); }}int tag_func_define_sprite(SwfdecDecoder *s){ bits_t *bits = &s->b; int id; SwfdecObject *object; SwfdecDecoder *sprite; int ret; id = get_u16(bits); object = swfdec_object_new(s,id); SWF_DEBUG(0," ID: %d\n", object->id); sprite = swfdec_decoder_new(); object->priv = sprite; object->type = SWF_OBJECT_SPRITE; sprite->n_frames = get_u16(bits); sprite->main_sprite->n_frames = sprite->n_frames; SWF_DEBUG(0,"n_frames = %d\n",sprite->n_frames); sprite->state = SWF_STATE_PARSETAG; sprite->no_render = 1; sprite->width = s->width; sprite->height = s->height; memcpy(sprite->transform, s->transform, sizeof(double)*6); sprite->parse = *bits; /* massive hack */ sprite->objects = s->objects; ret = swf_parse(sprite); SWF_DEBUG(0," ret = %d\n", ret); *bits = sprite->parse; sprite->frame_number = 0; //dump_layers(sprite); return SWF_OK;}SwfdecSpriteSeg *swfdec_sprite_get_seg(SwfdecSprite *sprite, int depth, int frame){ SwfdecSpriteSeg *seg; GList *g; for(g=g_list_first(sprite->layers); g; g=g_list_next(g)){ seg = (SwfdecSpriteSeg *)g->data; if(seg->depth==depth && seg->first_frame <= frame && seg->last_frame > frame) return seg; } return NULL;}void swfdec_sprite_add_seg(SwfdecSprite *sprite, SwfdecSpriteSeg *segnew){ GList *g; SwfdecSpriteSeg *seg; for(g=g_list_first(sprite->layers); g; g=g_list_next(g)){ seg = (SwfdecSpriteSeg *)g->data; if(seg->depth < segnew->depth){ sprite->layers = g_list_insert_before(sprite->layers, g, segnew); return; } } sprite->layers = g_list_append(sprite->layers, segnew);}SwfdecSpriteSeg *swfdec_spriteseg_new(void){ SwfdecSpriteSeg *seg; seg = g_new0(SwfdecSpriteSeg, 1); return seg;}SwfdecSpriteSeg *swfdec_spriteseg_dup(SwfdecSpriteSeg *seg){ SwfdecSpriteSeg *newseg; newseg = g_new(SwfdecSpriteSeg,1); memcpy(newseg,seg,sizeof(*seg)); return newseg;}void swfdec_spriteseg_free(SwfdecSpriteSeg *seg){ g_free(seg);}int swfdec_spriteseg_place_object_2(SwfdecDecoder *s){ bits_t *bits = &s->b; int reserved; int has_compose; int has_name; int has_ratio; int has_color_transform; int has_matrix; int has_character; int move; int depth; SwfdecSpriteSeg *layer; SwfdecSpriteSeg *oldlayer; reserved = getbit(bits); has_compose = getbit(bits); has_name = getbit(bits); has_ratio = getbit(bits); has_color_transform = getbit(bits); has_matrix = getbit(bits); has_character = getbit(bits); move = getbit(bits); depth = get_u16(bits); /* reserved is somehow related to sprites */ SWF_DEBUG(0," reserved = %d\n",reserved); if(reserved){ SWF_DEBUG(4," reserved bits non-zero %d\n",reserved); } SWF_DEBUG(0," has_compose = %d\n",has_compose); SWF_DEBUG(0," has_name = %d\n",has_name); SWF_DEBUG(0," has_ratio = %d\n",has_ratio); SWF_DEBUG(0," has_color_transform = %d\n",has_color_transform); SWF_DEBUG(0," has_matrix = %d\n",has_matrix); SWF_DEBUG(0," has_character = %d\n",has_character); oldlayer = swfdec_sprite_get_seg(s->parse_sprite,depth, s->parse_sprite->parse_frame); if(oldlayer){ oldlayer->last_frame = s->parse_sprite->parse_frame; } layer = swfdec_spriteseg_new(); layer->depth = depth; layer->first_frame = s->parse_sprite->parse_frame; layer->last_frame = s->parse_sprite->n_frames; swfdec_sprite_add_seg(s->parse_sprite,layer); if(has_character){ layer->id = get_u16(bits); SWF_DEBUG(0," id = %d\n",layer->id); }else{ if(oldlayer) layer->id = oldlayer->id; } if(has_matrix){ get_art_matrix(bits,layer->transform); }else{ if(oldlayer) art_affine_copy(layer->transform,oldlayer->transform); } if(has_color_transform){ get_art_color_transform(bits, layer->color_mult, layer->color_add); syncbits(bits); }else{ if(oldlayer){ memcpy(layer->color_mult, oldlayer->color_mult,sizeof(double)*4); memcpy(layer->color_add, oldlayer->color_add,sizeof(double)*4); }else{ layer->color_mult[0] = 1; layer->color_mult[1] = 1; layer->color_mult[2] = 1; layer->color_mult[3] = 1; layer->color_add[0] = 0; layer->color_add[1] = 0; layer->color_add[2] = 0; layer->color_add[3] = 0; } } if(has_ratio){ layer->ratio = get_u16(bits); SWF_DEBUG(0," ratio = %d\n",layer->ratio); }else{ if(oldlayer) layer->ratio = oldlayer->ratio; } if(has_name){ free(get_string(bits)); } if(has_compose){ int id; id = get_u16(bits); SWF_DEBUG(4,"composing with %04x\n",id); } return SWF_OK;}int swfdec_spriteseg_remove_object(SwfdecDecoder *s){ int depth; SwfdecSpriteSeg *seg; int id; id = get_u16(&s->b); depth = get_u16(&s->b); seg = swfdec_sprite_get_seg(s->parse_sprite,depth, s->parse_sprite->parse_frame - 1); if(seg){ seg->last_frame = s->parse_sprite->parse_frame; } return SWF_OK;}int swfdec_spriteseg_remove_object_2(SwfdecDecoder *s){ int depth; SwfdecSpriteSeg *seg; depth = get_u16(&s->b); seg = swfdec_sprite_get_seg(s->parse_sprite,depth, s->parse_sprite->parse_frame - 1); if(seg){ seg->last_frame = s->parse_sprite->parse_frame; } return SWF_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -