{ S64 a = ((S64)a1*(S64)b1+(S64)a2*(S64)b2)>>16;
SFIXED result = (SFIXED)(a);
if(a!=result)
- fprintf(stderr, "Warning: overflow in matrix multiplication");
+ fprintf(stderr, "Warning: overflow in matrix multiplication\n");
return result;
}
SFIXED RFXSWF_QFIX(int zaehler,int nenner) // bildet Quotient von zwei INTs in SFIXED
case ST_DEFINEFONTALIGNZONES: //pseudodefine
case ST_DEFINEFONTNAME: //pseudodefine
case ST_DEFINETEXT:
+ case ST_DEFINEBINARY:
case ST_DEFINETEXT2:
case ST_DEFINESOUND:
case ST_DEFINESPRITE:
case ST_DEFINEBUTTONSOUND: {
int t;
callback(tag, tag->pos + base, callback_data);
+ swf_GetU16(tag); //button id
for(t=0;t<4;t++) {
int flags;
callback(tag, tag->pos + base, callback_data);
- swf_GetU16(tag); //sound id
+ U16 sound_id = swf_GetU16(tag); //sound id
+ if(!sound_id)
+ continue;
flags = swf_GetU8(tag);
if(flags&1)
swf_GetU32(tag); // in point
callback(tag, tag->pos + base, callback_data); //button id
break;
+ case ST_SYMBOLCLASS:
case ST_EXPORTASSETS: {
int num = swf_GetU16(tag);
int t;
}
} break;
+ case ST_DOABC:
+ case ST_RAWABC:
+ break;
+
case ST_FREECHARACTER: /* unusual tags, which all start with an ID */
case ST_NAMECHARACTER:
- case ST_DEFINEBINARY:
case ST_DEFINEFONTNAME:
case ST_GENERATORTEXT:
callback(tag, tag->pos + base, callback_data);
/* I never saw recursive sprites, but they are (theoretically)
possible, so better add base here again */
enumerateUsedIDs(tag2, tag->pos + base, callback, callback_data);
- swf_DeleteTag(tag2);
+ swf_DeleteTag(0, tag2);
swf_GetBlock(tag, NULL, len);
}
}
enumerateUsedIDs(t, 0, callbackFillin, &ptr);
}
-void swf_Relocate (SWF*swf, char*bitmap)
+char swf_Relocate (SWF*swf, char*bitmap)
{
TAG*tag;
int slaveids[65536];
memset(slaveids, -1, sizeof(slaveids));
tag = swf->firstTag;
+ char ok = 1;
+
+ int current_id=0;
+#define NEW_ID(n) \
+ for(current_id++;current_id<65536;current_id++) { \
+ if(!bitmap[current_id]) { \
+ n = current_id; \
+ break; \
+ } \
+ } \
+ if(current_id==65536) { \
+ fprintf(stderr, "swf_Relocate: Couldn't relocate: Out of IDs\n"); \
+ return 0; \
+ }
+
while(tag)
{
int num;
int *ptr;
- int t;
if(swf_isDefiningTag(tag))
{
if(!bitmap[id]) { //free
newid = id;
+ } else if(slaveids[id]>0) {
+ newid = slaveids[id];
+ } else {
+ NEW_ID(newid);
}
- else {
- newid = 0;
- for (t=1;t<65536;t++)
- {
- if(!bitmap[t])
- {
- newid = t;
- break;
- }
- }
- }
+
bitmap[newid] = 1;
slaveids[id] = newid;
if(num) {
ptr = (int*)rfx_alloc(sizeof(int)*num);
swf_GetUsedIDs(tag, ptr);
-
+ int t;
for(t=0;t<num;t++) {
int id = GET16(&tag->data[ptr[t]]);
if(slaveids[id]<0) {
- fprintf(stderr, "swf_Relocate: Mapping id (%d) never encountered before in %s\n", id,
- swf_TagGetName(tag));
+ if(!id && bitmap[id]) {
+ /* id 0 is only used in SWF versions >=9. It's the ID of
+ the main timeline. It's used in e.g. SYMBOLTAG tags, but
+ never defined, so if we're asked to reallocate it, we have
+ to allocate an ID for it on the fly. */
+ int newid;
+ NEW_ID(newid);
+ bitmap[newid] = 1;
+ slaveids[id] = newid;
+ id = newid;
+ } else if(!bitmap[id]) {
+ /* well- we don't know this id, but it's not reserved anyway, so just
+ leave it alone */
+ } else {
+ /* this actually happens with files created with Flash CS4 and never.
+ Apparently e.g. DefineButton tags are able to use forward declarations of objects. */
+ fprintf(stderr, "warning: Mapping id (%d) never encountered before in %s\n", id,
+ swf_TagGetName(tag));
+ int newid;
+ NEW_ID(newid);
+ id = slaveids[id] = newid;
+ ok = 0;
+ }
} else {
id = slaveids[id];
- PUT16(&tag->data[ptr[t]], id);
}
+ PUT16(&tag->data[ptr[t]], id);
}
+ free(ptr);
}
tag=tag->next;
}
+ return ok;
}
/* untested */
PUT16(&tag->data[ptr[t]], id);
}
}
+ free(ptr);
}
}
}
{
if(tag->id == ST_DEFINEFONT ||
tag->id == ST_DEFINEFONT2 ||
+ tag->id == ST_DEFINEFONT3 ||
tag->id == ST_DEFINEFONTINFO)
return 1;
return 0;
/* we found two identical tags- remap one
of them */
remap[id] = swf_GetDefineID(tag2);
- swf_DeleteTag(tag);
- if(tag == swf->firstTag)
- swf->firstTag = next;
+ swf_DeleteTag(swf, tag);
}
} else if(swf_isPseudoDefiningTag(tag)) {
int id = swf_GetDefineID(tag);
/* if this tag was remapped, we don't
need the helper tag anymore. Discard
it. */
- swf_DeleteTag(tag);
- if(tag == swf->firstTag)
- swf->firstTag = next;
+ swf_DeleteTag(swf, tag);
}
}