From 8bef54dce0a8a53a9b4b42e2491f7f14bfb58575 Mon Sep 17 00:00:00 2001 From: Matthias Kramm Date: Fri, 1 Jan 2010 20:15:51 -0800 Subject: [PATCH] refactored relocation --- lib/as3/abc.h | 10 +++- lib/as3/assets.c | 144 +++++++++++++++++++++++++++++++++--------------------- lib/as3/main.c | 10 ++-- 3 files changed, 105 insertions(+), 59 deletions(-) diff --git a/lib/as3/abc.h b/lib/as3/abc.h index 3b6a134..41496ed 100644 --- a/lib/as3/abc.h +++ b/lib/as3/abc.h @@ -34,7 +34,9 @@ DECLARE(abc_interface); DECLARE(abc_class); DECLARE(abc_exception); DECLARE(abc_asset); +DECLARE(asset_dependency); DECLARE_LIST(abc_asset); +DECLARE_LIST(asset_dependency); DECLARE_LIST(abc_exception); DECLARE_LIST(TAG); @@ -202,9 +204,15 @@ typedef struct _abc_script { trait_list_t*traits; } abc_script_t; +struct _asset_dependency { + abc_asset_t*asset; + int*patch; + int patch_size; +}; struct _abc_asset { TAG_list_t*tags; - abc_asset_list_t*dependencies; + U16 id; + asset_dependency_list_t*dependencies; }; abc_method_t* abc_nullmethod(abc_file_t*file); diff --git a/lib/as3/assets.c b/lib/as3/assets.c index 06fadd8..3800bc8 100644 --- a/lib/as3/assets.c +++ b/lib/as3/assets.c @@ -1,7 +1,50 @@ #include +#include "../types.h" #include "../rfxswf.h" #include "assets.h" +static void add_dependencies(asset_resolver_t*assets, abc_asset_t*asset, TAG*tag) +{ + int num = swf_GetNumUsedIDs(tag); + int*positions = malloc(sizeof(int)*num); + swf_GetUsedIDs(tag, positions); + int t; + for(t=0;tdata[positions[t]]); + + /* check whether we already processed this one */ + int s; + for(s=0;sdata[positions[s]])==id) break; //seen before + } + if(s!=t) continue; + + /* count number of occurences */ + int count=0; + for(s=t;sdata[positions[s]])==id) + count++; + } + + /* create dependency */ + NEW(asset_dependency_t,d); + d->asset = assets->id2asset[id]; + d->patch = malloc(sizeof(int)*count); + d->patch_size = count; + count = 0; + for(s=t;sdata[positions[s]])==id) + d->patch[count++] = positions[s]; + } + if(!d->asset) { + fprintf(stderr, "Error: ID %d referenced, but not defined\n", id); + } else { + list_append(asset->dependencies, d); + } + } + free(positions); +} + asset_resolver_t* swf_ParseAssets(SWF*swf) { NEW(asset_resolver_t,assets); @@ -23,23 +66,12 @@ 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); - } - } + add_dependencies(assets, asset, tag); } else if(swf_isPseudoDefiningTag(tag)) { abc_asset_t*asset = assets->id2asset[swf_GetDefineID(tag)]; if(asset) { list_append(asset->tags, tag); + add_dependencies(assets, asset, tag); } } else if(tag->id == ST_SYMBOLCLASS) { int t, num = swf_GetU16(tag); @@ -50,7 +82,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 +112,61 @@ 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) { + TAG_list_t*t = a->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); + asset_dependency_list_t*l = a->dependencies; 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); + dump_asset(fo, l->asset_dependency->asset, prefix2); l = l->next; } + free(prefix2); } 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)++; + TAG_list_t*tags = a->tags; + + asset_dependency_list_t*deps = a->dependencies; + while(deps) { + asset_dependency_t*dep = deps->asset_dependency; + tag = write_asset(tag, dep->asset, written, currentid); + int t; + for(t=0;tpatch_size;t++) { + PUT16(&tag->data[dep->patch[t]], dep->asset->id); + } + deps = deps->next; + } + + while(tags) { + swf_SetDefineID(tags->TAG, a->id); + tag = write_tag(tag, tags->TAG); + tags = tags->next; + } } return tag; } @@ -158,7 +197,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 +208,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 +221,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 +232,5 @@ TAG*swf_AssetsToTags(TAG*itag, asset_bundle_list_t*assets) l = l->next; } dict_destroy(written); - free(bitmap); return itag; } diff --git a/lib/as3/main.c b/lib/as3/main.c index 1ce83a6..a4d0e48 100644 --- a/lib/as3/main.c +++ b/lib/as3/main.c @@ -126,10 +126,14 @@ int main(int argn, char*argv[]) swf.movieSize.xmin = swf.movieSize.ymin = 0; swf.movieSize.xmax = 20*20; swf.movieSize.ymax = 10*20; - TAG*tag = (TAG*)as3_getassets(0); - if(!swf.firstTag && tag) swf.firstTag = tag; - while(tag && tag->next) tag = tag->next; + + TAG*tag = swf.firstTag = swf_InsertTag(0, ST_SETBACKGROUNDCOLOR); + swf_SetU8(tag, 0xff); + swf_SetU8(tag, 0xff); + swf_SetU8(tag, 0xff); + + tag = as3_getassets(tag); tag = swf_InsertTag(tag, ST_DOABC); if(!swf.firstTag && tag) swf.firstTag = tag; -- 1.7.10.4