X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=blobdiff_plain;f=lib%2Fmodules%2Fswftools.c;h=6baecd105477ed01f1b4bf1192854fc2dfc2dc61;hp=426ea41cd828f45c152545c18854cd59b3411d32;hb=879d0eec420fe0fd5ddcd56c8fe62b82a6744edd;hpb=4a566feb5f1074db505f5f8a78c7fdf487d94b9a diff --git a/lib/modules/swftools.c b/lib/modules/swftools.c index 426ea41..6baecd1 100644 --- a/lib/modules/swftools.c +++ b/lib/modules/swftools.c @@ -30,7 +30,7 @@ SFIXED RFXSWF_SP(SFIXED a1,SFIXED a2,SFIXED b1,SFIXED b2) { 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 @@ -123,6 +123,7 @@ U16 swf_GetDefineID(TAG * t) case ST_DEFINEFONTALIGNZONES: //pseudodefine case ST_DEFINEFONTNAME: //pseudodefine case ST_DEFINETEXT: + case ST_DEFINEBINARY: case ST_DEFINETEXT2: case ST_DEFINESOUND: case ST_DEFINESPRITE: @@ -583,10 +584,13 @@ void enumerateUsedIDs(TAG * tag, int base, void (*callback)(TAG*, int, void*), v 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 @@ -611,6 +615,7 @@ void enumerateUsedIDs(TAG * tag, int base, void (*callback)(TAG*, int, void*), v callback(tag, tag->pos + base, callback_data); //button id break; + case ST_SYMBOLCLASS: case ST_EXPORTASSETS: { int num = swf_GetU16(tag); int t; @@ -635,9 +640,12 @@ void enumerateUsedIDs(TAG * tag, int base, void (*callback)(TAG*, int, void*), v } } 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); @@ -961,17 +969,31 @@ void swf_GetUsedIDs(TAG * t, int * positions) 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)) { @@ -982,18 +1004,12 @@ void swf_Relocate (SWF*swf, char*bitmap) 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; @@ -1004,20 +1020,43 @@ void swf_Relocate (SWF*swf, char*bitmap) if(num) { ptr = (int*)rfx_alloc(sizeof(int)*num); swf_GetUsedIDs(tag, ptr); - + int t; for(t=0;tdata[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 */ @@ -1046,6 +1085,7 @@ void swf_Relocate2(SWF*swf, int*id2id) PUT16(&tag->data[ptr[t]], id); } } + free(ptr); } } } @@ -1128,6 +1168,7 @@ U8 swf_isFontTag(TAG*tag) { if(tag->id == ST_DEFINEFONT || tag->id == ST_DEFINEFONT2 || + tag->id == ST_DEFINEFONT3 || tag->id == ST_DEFINEFONTINFO) return 1; return 0;