📄 swf_parse.c
字号:
/* * GPAC - Multimedia Framework C SDK * * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / Scene Management sub-project * * GPAC 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, or (at your option) * any later version. * * GPAC 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; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */#include <gpac/nodes_mpeg4.h>#include <gpac/internal/swf_dev.h>#include <gpac/avparse.h>#ifndef GPAC_READ_ONLYconst char *swf_get_tag(u32 tag);u16 swf_get_od_id(SWFReader *read){ return ++read->prev_od_id;}u16 swf_get_es_id(SWFReader *read){ return ++read->prev_es_id;}void swf_init_decompress(SWFReader *read){ read->compressed = (read->sig[0] == 'C') ? 1 : 0; if (!read->compressed) return;}void swf_done_decompress(SWFReader *read){}GF_Err swf_seek_file_to(SWFReader *read, u32 size){ if (!read->compressed) return gf_bs_seek(read->bs, size); return GF_NOT_SUPPORTED;}u32 swf_get_file_pos(SWFReader *read){ if (!read->compressed) return (u32) gf_bs_get_position(read->bs); return 0;}u32 swf_read_data(SWFReader *read, char *data, u32 data_size){ if (!read->compressed) return gf_bs_read_data(read->bs, data, data_size); return 0;}u32 swf_read_int(SWFReader *read, u32 nbBits){ if (!read->compressed) return gf_bs_read_int(read->bs, nbBits); return 0;}s32 swf_read_sint(SWFReader *read, u32 nbBits){ s32 r = 0; u32 i; if (!nbBits)return 0; r = -1 * (s32) swf_read_int(read, 1); for (i=1; i<nbBits; i++){ r <<= 1; r |= swf_read_int(read, 1); } return r;}u32 swf_align(SWFReader *read){ if (!read->compressed) return gf_bs_align(read->bs); return 0;}void swf_skip_data(SWFReader *read, u32 size){ while (size && !read->ioerr) { swf_read_int(read, 8); size --; }}void swf_get_rec(SWFReader *read, SWFRec *rc){ u32 nbbits; swf_align(read); nbbits = swf_read_int(read, 5); rc->x = FLT2FIX( swf_read_sint(read, nbbits) * SWF_TWIP_SCALE ); rc->w = FLT2FIX( swf_read_sint(read, nbbits) * SWF_TWIP_SCALE ); rc->w -= rc->x; rc->y = FLT2FIX( swf_read_sint(read, nbbits) * SWF_TWIP_SCALE ); rc->h = FLT2FIX( swf_read_sint(read, nbbits) * SWF_TWIP_SCALE ); rc->h -= rc->y;}u32 swf_get_32(SWFReader *read){ u32 val, res; val = swf_read_int(read, 32); res = (val&0xFF); res <<=8; res |= ((val>>8)&0xFF); res<<=8; res |= ((val>>16)&0xFF); res<<=8; res|= ((val>>24)&0xFF); return res;}u16 swf_get_16(SWFReader *read){ u16 val, res; val = swf_read_int(read, 16); res = (val&0xFF); res <<=8; res |= ((val>>8)&0xFF); return res;}s16 swf_get_s16(SWFReader *read){ s16 val; u8 v1; v1 = swf_read_int(read, 8); val = swf_read_sint(read, 8); val = (val<<8)&0xFF00; val |= (v1&0xFF); return val;}u32 swf_get_color(SWFReader *read){ u32 res; res = 0xFF00; res |= swf_read_int(read, 8); res<<=8; res |= swf_read_int(read, 8); res<<=8; res |= swf_read_int(read, 8); return res;}u32 swf_get_argb(SWFReader *read){ u32 res, al; res = swf_read_int(read, 8); res<<=8; res |= swf_read_int(read, 8); res<<=8; res |= swf_read_int(read, 8); al = swf_read_int(read, 8); return ((al<<24) | res);}u32 swf_get_matrix(SWFReader *read, GF_Matrix2D *mat, Bool rescale){ u32 bits_read; u32 flag, nb_bits; memset(mat, 0, sizeof(GF_Matrix2D)); mat->m[0] = mat->m[4] = FIX_ONE; bits_read = swf_align(read); flag = swf_read_int(read, 1); bits_read += 1; if (flag) { nb_bits = swf_read_int(read, 5);#ifdef GPAC_FIXED_POINT mat->m[0] = swf_read_sint(read, nb_bits); mat->m[4] = swf_read_sint(read, nb_bits);#else mat->m[0] = (Float) swf_read_sint(read, nb_bits); mat->m[0] /= 0x10000; mat->m[4] = (Float) swf_read_sint(read, nb_bits); mat->m[4] /= 0x10000;#endif bits_read += 5 + 2*nb_bits; } flag = swf_read_int(read, 1); bits_read += 1; if (flag) { nb_bits = swf_read_int(read, 5); /*WATCHOUT FOR ORDER*/#ifdef GPAC_FIXED_POINT mat->m[3] = swf_read_sint(read, nb_bits); mat->m[1] = swf_read_sint(read, nb_bits);#else mat->m[3] = (Float) swf_read_sint(read, nb_bits); mat->m[3] /= 0x10000; mat->m[1] = (Float) swf_read_sint(read, nb_bits); mat->m[1] /= 0x10000;#endif bits_read += 5 + 2*nb_bits; } nb_bits = swf_read_int(read, 5); bits_read += 5 + 2*nb_bits; if (nb_bits) { mat->m[2] = FLT2FIX( swf_read_sint(read, nb_bits) * SWF_TWIP_SCALE ); mat->m[5] = FLT2FIX( swf_read_sint(read, nb_bits) * SWF_TWIP_SCALE ); } /*for gradients and bitmap texture transforms*/ if (rescale) { mat->m[0] = gf_mulfix(mat->m[0], FLT2FIX(SWF_TWIP_SCALE)); mat->m[1] = gf_mulfix(mat->m[1], FLT2FIX(SWF_TWIP_SCALE)); mat->m[3] = gf_mulfix(mat->m[3], FLT2FIX(SWF_TWIP_SCALE)); mat->m[4] = gf_mulfix(mat->m[4], FLT2FIX(SWF_TWIP_SCALE)); } return bits_read;}void swf_get_colormatrix(SWFReader *read, GF_ColorMatrix *cmat){ Bool has_add, has_mul; u32 nbbits; memset(cmat, 0, sizeof(GF_ColorMatrix)); cmat->m[0] = cmat->m[6] = cmat->m[12] = cmat->m[18] = FIX_ONE; swf_align(read); has_add = swf_read_int(read, 1); has_mul = swf_read_int(read, 1); nbbits = swf_read_int(read, 4); if (has_mul) { cmat->m[0] = FLT2FIX( swf_read_int(read, nbbits) * SWF_COLOR_SCALE ); cmat->m[6] = FLT2FIX( swf_read_int(read, nbbits) * SWF_COLOR_SCALE ); cmat->m[12] = FLT2FIX( swf_read_int(read, nbbits) * SWF_COLOR_SCALE ); cmat->m[18] = FLT2FIX( swf_read_int(read, nbbits) * SWF_COLOR_SCALE ); } if (has_add) { cmat->m[4] = FLT2FIX( swf_read_int(read, nbbits) * SWF_COLOR_SCALE ); cmat->m[9] = FLT2FIX( swf_read_int(read, nbbits) * SWF_COLOR_SCALE ); cmat->m[14] = FLT2FIX( swf_read_int(read, nbbits) * SWF_COLOR_SCALE ); cmat->m[19] = FLT2FIX( swf_read_int(read, nbbits) * SWF_COLOR_SCALE ); } cmat->identity = 0; if ((cmat->m[0] == cmat->m[6]) && (cmat->m[0] == cmat->m[12]) && (cmat->m[0] == cmat->m[18]) && (cmat->m[0] == FIX_ONE) && (cmat->m[4] == cmat->m[9]) && (cmat->m[4] == cmat->m[14]) && (cmat->m[4] == cmat->m[19]) && (cmat->m[4] == 0)) cmat->identity = 1;}char *swf_get_string(SWFReader *read){ char szName[1024]; u32 i = 0; while (1) { szName[i] = swf_read_int(read, 8); if (!szName[i]) break; i++; } return strdup(szName);}GF_Node *SWF_NewNode(SWFReader *read, u32 tag){ GF_Node *n = gf_node_new(read->load->scene_graph, tag); if (n) gf_node_init(n); return n;}Bool SWF_CheckDepth(SWFReader *read, u32 depth){ GF_Node *disp, *empty; if (read->max_depth > depth) return 1; /*modify display list*/ disp = gf_sg_find_node_by_name(read->load->scene_graph, "DISPLAYLIST"); empty = gf_sg_find_node_by_name(read->load->scene_graph, "EMPTYSHAPE"); while (read->max_depth<=depth) { gf_node_insert_child(disp, empty, -1); gf_node_register(empty, disp); read->max_depth++; } return 0;}SWFShapeRec *swf_new_shape_rec(){ SWFShapeRec *style; GF_SAFEALLOC(style, SWFShapeRec); GF_SAFEALLOC(style->path, SWFPath); return style;}SWFShapeRec *swf_clone_shape_rec(SWFShapeRec *old_sr){ SWFShapeRec *new_sr = (SWFShapeRec *)malloc(sizeof(SWFShapeRec)); memcpy(new_sr, old_sr, sizeof(SWFShapeRec)); new_sr->path = (SWFPath*)malloc(sizeof(SWFPath)); memset(new_sr->path, 0, sizeof(SWFPath)); if (old_sr->nbGrad) { new_sr->grad_col = (u32*)malloc(sizeof(u32) * old_sr->nbGrad); memcpy(new_sr->grad_col, old_sr->grad_col, sizeof(u32) * old_sr->nbGrad); new_sr->grad_ratio = (u8*)malloc(sizeof(u8) * old_sr->nbGrad); memcpy(new_sr->grad_ratio, old_sr->grad_ratio, sizeof(u8) * old_sr->nbGrad); } return new_sr;}/*parse/append fill and line styles*/void swf_parse_styles(SWFReader *read, u32 revision, SWFShape *shape, u32 *bits_fill, u32 *bits_line){ u32 i, j, count; SWFShapeRec *style; swf_align(read); /*get fill styles*/ count = swf_read_int(read, 8); if (revision && (count== 0xFF)) count = swf_get_16(read); if (count) { for (i=0; i<count; i++) { style = swf_new_shape_rec(); style->solid_col = 0xFF00FF00; style->type = swf_read_int(read, 8); /*gradient fill*/ if (style->type & 0x10) { swf_get_matrix(read, &style->mat, 1); swf_align(read); style->nbGrad = swf_read_int(read, 8); if (style->nbGrad) { style->grad_col = (u32 *) malloc(sizeof(u32) * style->nbGrad); style->grad_ratio = (u8 *) malloc(sizeof(u8) * style->nbGrad); for (j=0; j<style->nbGrad; j++) { style->grad_ratio[j] = swf_read_int(read, 8); if (revision==2) style->grad_col[j] = swf_get_argb(read); else style->grad_col[j] = swf_get_color(read); } style->solid_col = style->grad_col[0]; /*make sure we have keys between 0 and 1.0 for BIFS (0 and 255 in swf)*/ if (style->grad_ratio[0] != 0) { u32 i; u32 *grad_col; u8 *grad_ratio; grad_ratio = (u8 *) malloc(sizeof(u8) * (style->nbGrad+1)); grad_col = (u32 *) malloc(sizeof(u32) * (style->nbGrad+1)); grad_col[0] = style->grad_col[0]; grad_ratio[0] = 0; for (i=0; i<style->nbGrad; i++) { grad_col[i+1] = style->grad_col[i]; grad_ratio[i+1] = style->grad_ratio[i]; } free(style->grad_col); style->grad_col = grad_col; free(style->grad_ratio); style->grad_ratio = grad_ratio; style->nbGrad++; } if (style->grad_ratio[style->nbGrad-1] != 255) { u32 *grad_col = (u32*)malloc(sizeof(u32) * (style->nbGrad+1)); u8 *grad_ratio = (u8*)malloc(sizeof(u8) * (style->nbGrad+1)); memcpy(grad_col, style->grad_col, sizeof(u32) * style->nbGrad); memcpy(grad_ratio, style->grad_ratio, sizeof(u8) * style->nbGrad); grad_col[style->nbGrad] = style->grad_col[style->nbGrad-1]; grad_ratio[style->nbGrad] = 255; free(style->grad_col); style->grad_col = grad_col; free(style->grad_ratio); style->grad_ratio = grad_ratio; style->nbGrad++; } } else { style->solid_col = 0xFF; } } /*bitmap fill*/ else if (style->type & 0x40) { style->img_id = swf_get_16(read); if (style->img_id == 65535) { style->img_id = 0; style->type = 0; style->solid_col = 0xFF00FFFF; } swf_get_matrix(read, &style->mat, 1); } /*solid fill*/ else { if (revision==2) style->solid_col = swf_get_argb(read); else style->solid_col = swf_get_color(read); } gf_list_add(shape->fill_right, style); style = swf_clone_shape_rec(style); gf_list_add(shape->fill_left, style); } } swf_align(read); /*get line styles*/ count = swf_read_int(read, 8); if (revision && (count==0xFF)) count = swf_get_16(read); if (count) { for (i=0; i<count; i++) { style = swf_new_shape_rec(); gf_list_add(shape->lines, style); style->width = FLT2FIX( swf_get_16(read) * SWF_TWIP_SCALE ); if (revision==2) style->solid_col = swf_get_argb(read); else style->solid_col = swf_get_color(read); } } swf_align(read); *bits_fill = swf_read_int(read, 4); *bits_line = swf_read_int(read, 4);}void swf_path_realloc_pts(SWFPath *path, u32 nbPts){ path->pts = (SFVec2f*)realloc(path->pts, sizeof(SFVec2f) * (path->nbPts + nbPts));}void swf_path_add_com(SWFShapeRec *sr, SFVec2f pt, SFVec2f ctr, u32 type){ /*not an error*/ if (!sr) return; sr->path->types = (u32*)realloc(sr->path->types, sizeof(u32) * (sr->path->nbType+1)); sr->path->types[sr->path->nbType] = type; switch (type) { case 2: swf_path_realloc_pts(sr->path, 2); sr->path->pts[sr->path->nbPts] = ctr; sr->path->pts[sr->path->nbPts+1] = pt; sr->path->nbPts+=2; break; case 1: default: swf_path_realloc_pts(sr->path, 1); sr->path->pts[sr->path->nbPts] = pt; sr->path->nbPts++; break; } sr->path->nbType++;}void swf_referse_path(SWFPath *path){ u32 i, j, pti, ptj; u32 *types; SFVec2f *pts; if (path->nbType<=1) return; types = (u32 *) malloc(sizeof(u32) * path->nbType); pts = (SFVec2f *) malloc(sizeof(SFVec2f) * path->nbPts); /*need first moveTo*/ types[0] = 0; pts[0] = path->pts[path->nbPts - 1]; pti = path->nbPts - 2; ptj = 1; j=1; for (i=0; i<path->nbType-1; i++) { types[j] = path->types[path->nbType - i - 1]; switch (types[j]) { case 2: assert(ptj<=path->nbPts-2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -