#include <assert.h>
+#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;t<atag->num_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;
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;t<num;t++) {
- U16 id = GET16(&tag->data[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);
} 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);
}
}
-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;i<t->asset_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;i<t->num_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;
}
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);
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) {
for(t=0;t<file->classes->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);
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 {
l = l->next;
}
dict_destroy(written);
- free(bitmap);
return itag;
}