📄 swf_parse.c
字号:
swf_free_rec_list(shape.lines); if (n && has_styles) { char szDEF[1024]; sprintf(szDEF, "Shape%d", ID); read->load->ctx->max_node_id++; ID = read->load->ctx->max_node_id; gf_node_set_id(n, ID, szDEF); } return n;}SWFFont *SWF_FindFont(SWFReader *read, u32 ID){ u32 i, count; count = gf_list_count(read->fonts); for (i=0; i<count; i++) { SWFFont *ft = (SWFFont *)gf_list_get(read->fonts, i); if (ft->fontID==ID) return ft; } return NULL;}GF_Node *SWF_GetNode(SWFReader *read, u32 ID){ GF_Node *n; char szDEF[1024]; sprintf(szDEF, "Shape%d", ID); n = gf_sg_find_node_by_name(read->load->scene_graph, szDEF); if (n) return n; sprintf(szDEF, "Text%d", ID); n = gf_sg_find_node_by_name(read->load->scene_graph, szDEF); if (n) return n; sprintf(szDEF, "Button%d", ID); n = gf_sg_find_node_by_name(read->load->scene_graph, szDEF); if (n) return n; return NULL;}DispShape *SWF_GetDepthEntry(SWFReader *read, u32 Depth, Bool create){ u32 i; DispShape *tmp; i=0; while ((tmp = (DispShape *)gf_list_enum(read->display_list, &i))) { if (tmp->depth == Depth) return tmp; } if (!create) return NULL; GF_SAFEALLOC(tmp , DispShape); tmp->depth = Depth; tmp->n = NULL; gf_list_add(read->display_list, tmp); memset(&tmp->mat, 0, sizeof(GF_Matrix2D)); tmp->mat.m[0] = tmp->mat.m[4] = FIX_ONE; memset(&tmp->cmat, 0, sizeof(GF_ColorMatrix)); tmp->cmat.m[0] = tmp->cmat.m[6] = tmp->cmat.m[12] = tmp->cmat.m[18] = FIX_ONE; tmp->cmat.identity = 1; return tmp;}GF_Err swf_func_skip(SWFReader *read){ swf_skip_data(read, read->size); return read->ioerr;}GF_Err swf_unknown_tag(SWFReader *read){ swf_report(read, GF_NOT_SUPPORTED, "Tag not implemented - skipping"); return swf_func_skip(read);}GF_Err swf_set_backcol(SWFReader *read){ u32 col; GF_Command *com; GF_CommandField *f; com = gf_sg_command_new(read->load->scene_graph, GF_SG_FIELD_REPLACE); com->node = gf_sg_find_node_by_name(read->load->scene_graph, "BACKGROUND"); gf_node_register(com->node, NULL); f = gf_sg_command_field_new(com); f->field_ptr = gf_sg_vrml_field_pointer_new(GF_SG_VRML_SFCOLOR); f->fieldType = GF_SG_VRML_SFCOLOR; f->fieldIndex = 1; /*backColor index*/ col = swf_get_color(read); ((SFColor *)f->field_ptr)->red = INT2FIX((col>>16) & 0xFF) / 255; ((SFColor *)f->field_ptr)->green = INT2FIX((col>>8) & 0xFF) / 255; ((SFColor *)f->field_ptr)->blue = INT2FIX((col) & 0xFF) / 255; gf_list_add(read->bifs_au->commands, com); return GF_OK;}GF_Err SWF_InsertNode(SWFReader *read, GF_Node *n){ GF_Command *com; GF_CommandField *f; if (read->flags & GF_SM_SWF_STATIC_DICT) { M_Switch *par = (M_Switch *)gf_sg_find_node_by_name(read->load->scene_graph, "DICTIONARY"); gf_node_list_add_child(&par->choice, n); gf_node_register((GF_Node *)n, (GF_Node *)par); } else { com = gf_sg_command_new(read->load->scene_graph, GF_SG_INDEXED_INSERT); com->node = gf_sg_find_node_by_name(read->load->scene_graph, "DICTIONARY"); gf_node_register(com->node, NULL); f = gf_sg_command_field_new(com); f->field_ptr = &f->new_node; f->fieldType = GF_SG_VRML_SFNODE; f->fieldIndex = 0; /*choice index*/ f->pos = -1; f->new_node = n; gf_node_register(f->new_node, NULL); gf_list_add(read->bifs_au->commands, com); } return GF_OK;}GF_Err swf_def_shape(SWFReader *read, u32 revision){ GF_Node *new_node; new_node = swf_parse_shape_def(read, 1, revision); if (!new_node) return GF_OK; return SWF_InsertNode(read, new_node);}typedef struct{ Bool hitTest, down, over, up; u32 character_id; u16 depth; GF_Matrix2D mx; GF_ColorMatrix cmx;} SWF_ButtonRecord;GF_Err swf_def_button(SWFReader *read, u32 revision){ char szName[1024]; SWF_ButtonRecord recs[40]; u32 i, ID, nb_but_rec; M_Switch *button; Bool has_actions; has_actions = 0; ID = swf_get_16(read); if (revision==1) { gf_bs_read_int(read->bs, 7); gf_bs_read_int(read->bs, 1); has_actions = swf_get_16(read); } nb_but_rec = 0; while (1) { SWF_ButtonRecord *rec = &recs[nb_but_rec]; gf_bs_read_int(read->bs, 4); rec->hitTest = gf_bs_read_int(read->bs, 1); rec->down = gf_bs_read_int(read->bs, 1); rec->over = gf_bs_read_int(read->bs, 1); rec->up = gf_bs_read_int(read->bs, 1); if (!rec->hitTest && !rec->up && !rec->over && !rec->down) break; rec->character_id = swf_get_16(read); rec->depth = swf_get_16(read); swf_get_matrix(read, &rec->mx, 0); if (revision==1) swf_get_colormatrix(read, &rec->cmx); else gf_cmx_init(&rec->cmx); gf_bs_align(read->bs); nb_but_rec++; } if (revision==0) { while (1) { u32 act_type = gf_bs_read_u8(read->bs); if (!act_type) break; if (act_type > 0x80) { u32 len = swf_get_16(read); gf_bs_skip_bytes(read->bs, len); } } } else { while (has_actions) { has_actions = swf_get_16(read); swf_get_16(read); while (1) { u32 act_type = gf_bs_read_u8(read->bs); if (act_type > 0x80) { u32 len = swf_get_16(read); gf_bs_skip_bytes(read->bs, len); } } } } button = (M_Switch *) SWF_NewNode(read, TAG_MPEG4_Switch); sprintf(szName, "Button%d", ID); read->load->ctx->max_node_id++; ID = read->load->ctx->max_node_id; gf_node_set_id((GF_Node *)button, ID, szName); SWF_InsertNode(read, (GF_Node *)button); /*by default show first character*/ button->whichChoice = 0; for (i=0; i<nb_but_rec; i++) { GF_Node *character = SWF_GetNode(read, recs[i].character_id); if (character) { gf_node_list_add_child(&button->choice, character); gf_node_register(character, (GF_Node *)button); } } return GF_OK;}Bool swf_mat_is_identity(GF_Matrix2D *mat){ if (mat->m[0] != FIX_ONE) return 0; if (mat->m[4] != FIX_ONE) return 0; if (mat->m[1] != FIX_ONE) return 0; if (mat->m[2] != FIX_ONE) return 0; if (mat->m[3] != FIX_ONE) return 0; if (mat->m[5] != FIX_ONE) return 0; return 1;}enum{ SWF_PLACE, SWF_REPLACE, SWF_MOVE,};GF_Err swf_place_obj(SWFReader *read, u32 revision){ GF_Command *com; GF_CommandField *f; u32 ID, bitsize, ratio; u32 clip_depth; GF_Matrix2D mat; GF_ColorMatrix cmat; GF_Node *shape, *par; DispShape *ds; char *name; char szDEF[100]; u32 depth, type; Bool had_depth, is_sprite; /*SWF flags*/ Bool has_clip, has_name, has_ratio, has_cmat, has_mat, has_id, has_move; name = NULL; clip_depth = 0; ID = 0; depth = 0; has_clip = has_name = has_ratio = has_cmat = has_mat = has_id = has_move = 0; gf_cmx_init(&cmat); gf_mx2d_init(mat); /*place*/ type = SWF_PLACE; /*SWF 1.0*/ if (revision==0) { ID = swf_get_16(read); has_id = 1; depth = swf_get_16(read); bitsize = 32; bitsize += swf_get_matrix(read, &mat, 0); has_mat = 1; /*size exceeds matrix, parse col mat*/ if (bitsize < read->size*8) { swf_get_colormatrix(read, &cmat); has_cmat = 1; swf_align(read); } } /*SWF 3.0*/ else if (revision==1) { /*reserved*/ swf_read_int(read, 1); has_clip = swf_read_int(read, 1); has_name = swf_read_int(read, 1); has_ratio = swf_read_int(read, 1); has_cmat = swf_read_int(read, 1); has_mat = swf_read_int(read, 1); has_id = swf_read_int(read, 1); has_move = swf_read_int(read, 1); depth = swf_get_16(read); if (has_id) ID = swf_get_16(read); if (has_mat) { swf_get_matrix(read, &mat, 0); swf_align(read); } if (has_cmat) { swf_get_colormatrix(read, &cmat); swf_align(read); } if (has_ratio) ratio = swf_get_16(read); if (has_clip) clip_depth = swf_get_16(read); if (has_name) { name = swf_get_string(read); free(name); } /*replace*/ if (has_id && has_move) type = SWF_REPLACE; /*move*/ else if (!has_id && has_move) type = SWF_MOVE; /*place*/ else type = SWF_PLACE; } if (clip_depth) { swf_report(read, GF_NOT_SUPPORTED, "Clipping not supported - ignoring"); return GF_OK; } /*1: check depth of display list*/ had_depth = SWF_CheckDepth(read, depth); /*check validity*/ if ((type==SWF_MOVE) && !had_depth) swf_report(read, GF_BAD_PARAM, "Accessing empty depth level %d", depth); ds = NULL; shape = NULL; /*usual case: (re)place depth level*/ switch (type) { case SWF_MOVE: ds = SWF_GetDepthEntry(read, depth, 0); shape = ds ? ds->n : NULL; break; case SWF_REPLACE: case SWF_PLACE: default: assert(has_id); shape = SWF_GetNode(read, ID); break; } is_sprite = 0; if (!shape) { /*this may be a sprite*/ if (type != SWF_MOVE) { sprintf(szDEF, "Sprite%d_root", ID); shape = gf_sg_find_node_by_name(read->load->scene_graph, szDEF); if (shape) is_sprite = 1; } if (!shape) { swf_report(read, GF_BAD_PARAM, "%s unfound object (ID %d)", (type==SWF_MOVE) ? "Moving" : ((type==SWF_PLACE) ? "Placing" : "Replacing"), ID); return GF_OK; } } /*restore prev matrix if needed*/ if (type==SWF_REPLACE) { if (!ds) ds = SWF_GetDepthEntry(read, depth, 0); if (ds) { if (!has_mat) { memcpy(&mat, &ds->mat, sizeof(GF_Matrix2D)); has_mat = 1; } if (!has_cmat) { memcpy(&cmat, &ds->cmat, sizeof(GF_ColorMatrix)); has_cmat = 1; } } } /*check for identity matrices*/ if (has_cmat && cmat.identity) has_cmat = 0; if (has_mat && swf_mat_is_identity(&mat)) has_mat = 0; /*then add cmat/mat and node*/ par = NULL; if (!has_mat && !has_cmat) { par = shape; } else { if (has_mat) par = SWF_GetBIFSMatrix(read, &mat); if (has_cmat) { GF_Node *cm = SWF_GetBIFSColorMatrix(read, &cmat); if (!par) { par = cm; gf_node_insert_child(par, shape, -1); gf_node_register(shape, par); } else { gf_node_insert_child(par, cm, -1); gf_node_register(cm, par); gf_node_insert_child(cm, shape, -1); gf_node_register(shape, cm); } } else { gf_node_insert_child(par, shape, -1); gf_node_register(shape, par); } } /*store in display list*/ ds = SWF_GetDepthEntry(read, depth, 1); ds->n = shape; /*remember matrices*/ memcpy(&ds->mat, &mat, sizeof(GF_Matrix2D)); memcpy(&ds->cmat, &cmat, sizeof(GF_ColorMatrix)); /*and write command*/ com = gf_sg_command_new(read->load->scene_graph, GF_SG_INDEXED_REPLACE); /*in sprite definiton, modify at sprite root level*/ if (0 && read->current_sprite_id) { sprintf(szDEF, "Sprite%d_root", read->current_sprite_id); com->node = gf_sg_find_node_by_name(read->load->scene_graph, szDEF); depth = 0; } else { com->node = gf_sg_find_node_by_name(read->load->scene_graph, "DISPLAYLIST"); } gf_node_register(com->node, NULL); f = gf_sg_command_field_new(com); f->field_ptr = &f->new_node; f->fieldType = GF_SG_VRML_SFNODE; f->pos = depth; f->fieldIndex = 2; /*children index*/ f->new_node = par; gf_node_register(f->new_node, com->node); gf_list_add(read->bifs_au->commands, com); /*starts anim*/ if (is_sprite) { sprintf(szDEF, "Sprite%d_ctrl", ID); com = gf_sg_command_new(read->load->scene_graph, GF_SG_FIELD_REPLACE); com->node = gf_sg_find_node_by_name(read->load->scene_graph, szDEF); gf_node_register(com->node, NULL); f = gf_sg_command_field_new(com); f->field_ptr = gf_sg_vrml_field_pointer_new(GF_SG_VRML_SFTIME); *(SFTime *)f->field_ptr = ((Double) (s64) read->bifs_au->timing) / read->bifs_es->timeScale; f->fieldType = GF_SG_VRML_SFTIME; f->fieldIndex = 2; /*startTime index*/ gf_list_add(read->bifs_au->commands, com); } return GF_OK;}GF_Err swf_remove_obj(SWFReader *read, u32 revision){ GF_Command *com; GF_CommandField *f; DispShape *ds; u32 depth; if (revision==0) swf_get_16(read); depth = swf_get_16(read); ds = SWF_GetDepthEntry(read, depth, 0); /*this happens if a placeObject has failed*/ if (!ds) return GF_OK; ds->n = NULL; com = gf_sg_command_new(read->load->scene_graph, GF_SG_INDEXED_REPLACE); com->node = gf_sg_find_node_by_name(read->load->scene_graph, "DISPLAYLIST"); gf_node_register(com->node, NULL); f = gf_sg_command_field_new(com); f->field_ptr = &f->new_node; f->fieldType = GF_SG_VRML_SFNODE; f->pos = depth; f->fieldIndex = 2; /*children index*/ f->new_node = gf_sg_find_node_by_name(read->load->scene_graph, "EMPTYSHAPE"); gf_node_register(f->new_node, com->node); gf_list_add(read->bifs_au->commands, com); return GF_OK;}GF_Err swf_show_frame(SWFReader *read){ u32 ts; Bool is_rap; /*hack to allow for empty BIFS AU to be encoded in order to keep the frame-rate (this reduces MP4 table size...)*/ if (0 && !gf_list_count(read->bifs_au->commands)) { GF_Command *com; GF_CommandField *f; com = gf_sg_command_new(read->load->scene_graph, GF_SG_FIELD_REPLACE); com->node = gf_sg_find_node_by_name(read->load->scene_graph, "DICTIONARY"); gf_node_register(com->node, NULL); f = gf_sg_command_field_new(com); f->field_ptr = gf_sg_vrml_field_pointer_new(GF_SG_VRML_SFINT32); f->fieldType = GF_SG_VRML_SFINT32; f->fieldIndex = 1; /*whichCoice index*/ /*replace by same value*/ *((SFInt32 *)f->field_ptr) = -1; gf_list_add(read->bifs_au->commands, com); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -