X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=blobdiff_plain;f=lib%2Fas3%2Fassets.c;h=f6b4aee8720710140a71d63ac78704b0fe841b76;hp=06fadd87a12059cdf075a9ce07bff107182dc97f;hb=86683e9e9c61cb3f0164a1ffcf151ccefa8871df;hpb=9ed9a87914fc9a590967d46de404e0f6290b7bb2 diff --git a/lib/as3/assets.c b/lib/as3/assets.c index 06fadd8..f6b4aee 100644 --- a/lib/as3/assets.c +++ b/lib/as3/assets.c @@ -1,18 +1,38 @@ #include +#include "../types.h" #include "../rfxswf.h" #include "assets.h" +static void add_dependencies(asset_resolver_t*assets, abc_asset_t*asset, asset_tag_t*atag) +{ + TAG*tag = atag->tag; + atag->num_deps = swf_GetNumUsedIDs(tag); + int*positions = malloc(sizeof(int)*atag->num_deps); + atag->deps = malloc(atag->num_deps*sizeof(atag->deps[0])); + swf_GetUsedIDs(tag, positions); + int t; + for(t=0;tnum_deps;t++) { + asset_dependency_t*d = &atag->deps[t]; + d->patch_pos = positions[t]; + U16 id = GET16(&tag->data[positions[t]]); + d->asset = assets->id2asset[id]; + if(!d->asset) { + fprintf(stderr, "Error: ID %d referenced, but not defined\n", id); + } + } + free(positions); +} + 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); + assets->id2asset = rfx_calloc(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; @@ -23,23 +43,19 @@ asset_resolver_t* swf_ParseAssets(SWF*swf) 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); - } + if(asset) { + NEW(asset_tag_t,t); + t->tag = tag; + list_append(asset->tags, t); + add_dependencies(assets, asset, t); } } else if(swf_isPseudoDefiningTag(tag)) { abc_asset_t*asset = assets->id2asset[swf_GetDefineID(tag)]; if(asset) { - list_append(asset->tags, tag); + NEW(asset_tag_t,t); + t->tag = tag; + list_append(asset->tags, t); + add_dependencies(assets, asset, t); } } else if(tag->id == ST_SYMBOLCLASS) { int t, num = swf_GetU16(tag); @@ -50,7 +66,7 @@ asset_resolver_t* swf_ParseAssets(SWF*swf) } else { abc_asset_t*asset = assets->id2asset[id]; if(!asset) { - fprintf(stderr, "Error: ID %d referenced, but not defined\n", id); + fprintf(stderr, "Error: ID %d referenced, but not defined.\n", id); } else { char*name = swf_GetString(tag); dict_put(assets->name2asset, name, asset); @@ -80,54 +96,57 @@ void swf_ResolveAssets(asset_resolver_t*assets, abc_file_t*file) } } -static void dump_asset_list(FILE*fo, abc_asset_list_t*l, const char*prefix) +static void dump_asset(FILE*fo, abc_asset_t*a, 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; - } + asset_tag_list_t*t = a->tags; + while(t) { + TAG*tag = t->asset_tag->tag; + fprintf(fo, "%s[tag] %s defines ID %d\n", prefix, swf_TagGetName(tag), swf_GetDefineID(tag)); char*prefix2 = allocprintf("%s ", prefix); - dump_asset_list(fo, l->abc_asset->dependencies, prefix2); + int i; + for(i=0;iasset_tag->num_deps;i++) { + asset_dependency_t*d = &t->asset_tag->deps[i]; + dump_asset(fo, d->asset, prefix2); + } free(prefix2); - l = l->next; + t = t->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); + dump_asset(fo, asset, prefix); } -static TAG* write_tag(TAG*prev, TAG*tag, dict_t*written) +static TAG* write_tag(TAG*prev, TAG*tag) { - if(!dict_contains(written, tag)) { - dict_put(written, tag, 0); - if(prev) { - prev->next = tag; - } - tag->prev = prev; - tag->next = 0; - prev = tag; + 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) +static TAG*write_asset(TAG*tag, abc_asset_t*a, dict_t*written, U16*currentid) { - 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; + if(!dict_contains(written, a)) { + dict_put(written, a, 0); + a->id = (*currentid)++; + asset_tag_list_t*tags = a->tags; + + while(tags) { + asset_tag_t*t = tags->asset_tag; + int i; + for(i=0;inum_deps;i++) { + asset_dependency_t*dep = &t->deps[i]; + tag = write_asset(tag, dep->asset, written, currentid); + PUT16(&t->tag->data[dep->patch_pos], dep->asset->id); + } + swf_SetDefineID(t->tag, a->id); + tag = write_tag(tag, t->tag); + tags = tags->next; + } } return tag; } @@ -148,7 +167,7 @@ void swf_WriteABCSymbols(TAG*tag, abc_file_t*file) 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); + U16 id = swf_GetDefineID(a->tags->asset_tag->tag); char*fullname = abc_class_fullname(cls); swf_SetU16(tag, id); swf_SetString(tag, fullname); @@ -158,7 +177,7 @@ void swf_WriteABCSymbols(TAG*tag, abc_file_t*file) TAG*swf_AssetsToTags(TAG*itag, asset_bundle_list_t*assets) { - char* bitmap = rfx_calloc(sizeof(char)*65536); + U16 currentid = 1; asset_bundle_list_t*l = assets; dict_t*written = dict_new2(&ptr_type); while(l) { @@ -169,10 +188,10 @@ TAG*swf_AssetsToTags(TAG*itag, asset_bundle_list_t*assets) 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 = write_asset(tag, a, written, ¤tid); } } - + tag = swf_InsertTag(tag, ST_DOABC); swf_WriteABC(tag, file); tag = swf_InsertTag(tag, ST_SYMBOLCLASS); @@ -182,10 +201,6 @@ TAG*swf_AssetsToTags(TAG*itag, asset_bundle_list_t*assets) 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 { @@ -197,6 +212,5 @@ TAG*swf_AssetsToTags(TAG*itag, asset_bundle_list_t*assets) l = l->next; } dict_destroy(written); - free(bitmap); return itag; }