X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fas3%2Fassets.c;fp=lib%2Fas3%2Fassets.c;h=06fadd87a12059cdf075a9ce07bff107182dc97f;hb=9ed9a87914fc9a590967d46de404e0f6290b7bb2;hp=0000000000000000000000000000000000000000;hpb=8f67c24d3250b417099a27525c3ef14ab1c7b3db;p=swftools.git diff --git a/lib/as3/assets.c b/lib/as3/assets.c new file mode 100644 index 0000000..06fadd8 --- /dev/null +++ b/lib/as3/assets.c @@ -0,0 +1,202 @@ +#include +#include "../rfxswf.h" +#include "assets.h" + +asset_resolver_t* swf_ParseAssets(SWF*swf) +{ + NEW(asset_resolver_t,assets); + assets->name2asset = dict_new2(&charptr_type); + assets->id2asset = malloc(sizeof(abc_asset_t*)*65536); + + TAG*tag = swf->firstTag; + while(tag) { + if(swf_isDefiningTag(tag)) { + NEW(abc_asset_t, asset); + list_append(asset->tags, tag); + assets->id2asset[swf_GetDefineID(tag)] = asset; + } + tag = tag->next; + } + + tag = swf->firstTag; + while(tag) { + if(swf_isDefiningTag(tag)) { + abc_asset_t*asset = assets->id2asset[swf_GetDefineID(tag)]; + assert(asset); + int num = swf_GetNumUsedIDs(tag); + int*positions = malloc(sizeof(int)*num); + swf_GetUsedIDs(tag, positions); + int t; + for(t=0;tdata[positions[t]]); + abc_asset_t*a = assets->id2asset[id]; + if(!a) { + fprintf(stderr, "Error: ID %d referenced, but not defined\n", id); + } else { + list_append(asset->dependencies, a); + } + } + } else if(swf_isPseudoDefiningTag(tag)) { + abc_asset_t*asset = assets->id2asset[swf_GetDefineID(tag)]; + if(asset) { + list_append(asset->tags, tag); + } + } else if(tag->id == ST_SYMBOLCLASS) { + int t, num = swf_GetU16(tag); + for(t=0;tmainclass_id = id; + } else { + abc_asset_t*asset = assets->id2asset[id]; + if(!asset) { + fprintf(stderr, "Error: ID %d referenced, but not defined\n", id); + } else { + char*name = swf_GetString(tag); + dict_put(assets->name2asset, name, asset); + } + } + } + } + tag = tag->next; + } + return assets; +} + +void swf_ResolveAssets(asset_resolver_t*assets, abc_file_t*file) +{ + int num = assets->name2asset->num; + int resolved = 0; + int t; + for(t=0;tclasses->num;t++) { + abc_class_t*cls = (abc_class_t*)array_getvalue(file->classes, t); + char*fullname = abc_class_fullname(cls); + abc_asset_t*a = (abc_asset_t*)dict_lookup(assets->name2asset, fullname); + if(a) { + resolved++; + cls->asset = a; + } + free(fullname); + } +} + +static void dump_asset_list(FILE*fo, abc_asset_list_t*l, const char*prefix) +{ + while(l) { + TAG_list_t*t = l->abc_asset->tags; + while(t) { + TAG*tag = t->TAG; + fprintf(fo, "%s[tag] %s defines ID %d\n", prefix, swf_TagGetName(tag), swf_GetDefineID(tag)); + t = t->next; + } + char*prefix2 = allocprintf("%s ", prefix); + dump_asset_list(fo, l->abc_asset->dependencies, prefix2); + free(prefix2); + l = l->next; + } +} + +void swf_DumpAsset(FILE*fo, abc_asset_t*asset, const char*prefix) +{ + abc_asset_list_t*l = 0; + list_append(l, asset); + dump_asset_list(fo, l, prefix); + list_free(l); +} + +static TAG* write_tag(TAG*prev, TAG*tag, dict_t*written) +{ + if(!dict_contains(written, tag)) { + dict_put(written, tag, 0); + if(prev) { + prev->next = tag; + } + tag->prev = prev; + tag->next = 0; + prev = tag; + } + return prev; +} +static TAG*write_asset(TAG*tag, abc_asset_t*a, dict_t*written) +{ + TAG_list_t*tags = a->tags; + abc_asset_list_t*deps = a->dependencies; + while(deps) { + tag = write_asset(tag, deps->abc_asset, written); + deps = deps->next; + } + while(tags) { + tag = write_tag(tag, tags->TAG, written); + tags = tags->next; + } + return tag; +} + +void swf_WriteABCSymbols(TAG*tag, abc_file_t*file) +{ + int num = 0; + int t; + for(t=0;tclasses->num;t++) { + abc_class_t*cls = (abc_class_t*)array_getvalue(file->classes, t); + abc_asset_t*a = cls->asset; + if(a && a->tags) { + num++; + } + } + swf_SetU16(tag, num); + for(t=0;tclasses->num;t++) { + abc_class_t*cls = (abc_class_t*)array_getvalue(file->classes, t); + abc_asset_t*a = cls->asset; + if(a && a->tags) { + U16 id = swf_GetDefineID(a->tags->TAG); + char*fullname = abc_class_fullname(cls); + swf_SetU16(tag, id); + swf_SetString(tag, fullname); + } + } +} + +TAG*swf_AssetsToTags(TAG*itag, asset_bundle_list_t*assets) +{ + char* bitmap = rfx_calloc(sizeof(char)*65536); + asset_bundle_list_t*l = assets; + dict_t*written = dict_new2(&ptr_type); + while(l) { + if(l->asset_bundle->used) { + abc_file_t*file = l->asset_bundle->file; + int t; + TAG* tag = 0; + for(t=0;tclasses->num;t++) { + abc_asset_t*a = ((abc_class_t*)array_getvalue(file->classes, t))->asset; + if(a) { + tag = write_asset(tag, a, written); + } + } + + tag = swf_InsertTag(tag, ST_DOABC); + swf_WriteABC(tag, file); + tag = swf_InsertTag(tag, ST_SYMBOLCLASS); + swf_WriteABCSymbols(tag, file); + + TAG*first = tag; + while(first && first->prev) + first=first->prev; + + SWF swf; + memset(&swf, 0, sizeof(SWF)); + swf.firstTag = first; + swf_Relocate(&swf, bitmap); + if(!itag) { + itag = first; + } else { + itag->next = first; + first->prev = itag; + itag = tag; + } + } + l = l->next; + } + dict_destroy(written); + free(bitmap); + return itag; +}