From: kramm Date: Sat, 23 Mar 2002 21:23:36 +0000 (+0000) Subject: added functions for extracting positions of referred IDs X-Git-Tag: xpdf-0-92~48 X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=commitdiff_plain;h=0ee8530d9e3fc453e1f97fa2623f5db344622a40 added functions for extracting positions of referred IDs --- diff --git a/lib/modules/swftools.c b/lib/modules/swftools.c index a1befc2..4117fc3 100644 --- a/lib/modules/swftools.c +++ b/lib/modules/swftools.c @@ -282,3 +282,327 @@ char* swf_GetName(TAG * t) return name; } +void enumerateUsedIDs_styles(TAG * tag, void (*callback)(TAG*, int, void*), void*callback_data, int num) +{ + U16 count; + int t; + count = swf_GetU8(tag); + if(count == 0xff && num>1) // defineshape2,3 only + count = swf_GetU16(tag); + + for(t=0;t=3?1:0); + } + else if(type == 0x40 || type == 0x41) + { + swf_ResetReadBits(tag); + // we made it. + if(tag->data[tag->pos] != 0xff || + tag->data[tag->pos+1] != 0xff) + (callback)(tag, tag->pos, callback_data); + + swf_GetU16(tag); + swf_ResetReadBits(tag); + swf_GetMatrix(tag, NULL); + } + else { + fprintf(stderr, "rfxswf:swftools.c Unknown fillstyle:0x%02x\n",type); + } + } + swf_ResetReadBits(tag); + count = swf_GetU8(tag); // line style array + if(count == 0xff) + count = swf_GetU16(tag); + for(t=0;tpos = 0; + switch(tag->id) + { + case ST_DEFINEBUTTONCXFORM: { + int t; + callback(tag, tag->pos + base, callback_data); + for(t=0;t<4;t++) { + int flags; + callback(tag, tag->pos + base, callback_data); + swf_GetU16(tag); //sound id + flags = swf_GetU8(tag); + if(flags&1) + swf_GetU32(tag); // in point + if(flags&2) + swf_GetU32(tag); // out points + if(flags&4) + swf_GetU16(tag); // loop count + if(flags&8) + { + int npoints = swf_GetU8(tag); + int s; + for(s=0;spos + base, callback_data); //button id + break; + case ST_PLACEOBJECT: + callback(tag, tag->pos + base, callback_data); + break; + case ST_PLACEOBJECT2: + // only if placeflaghascharacter + if(!(tag->data[0]&2)) + break; + callback(tag, 3 + base, callback_data); + break; + case ST_REMOVEOBJECT: + callback(tag, tag->pos + base, callback_data); + break; + case ST_STARTSOUND: + callback(tag, tag->pos + base, callback_data); + break; + case ST_DEFINESPRITE: { + if(tag->len <= 4) + break; // sprite is expanded + + swf_GetU16(tag); // id + swf_GetU16(tag); // framenum + + while(1) { + U16 flags = swf_GetU16(tag); + U32 len; + U16 id = flags>>6; + TAG *tag2 = swf_InsertTag(NULL, id); + len = flags&0x3f; + if(len == 63) + len = swf_GetU32(tag); + if(id == ST_END) + break; + tag2->len = tag2->memsize = len; + tag2->data = malloc(len); + memcpy(tag2->data, &tag->data[tag->pos], len); + /* 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_GetBlock(tag, NULL, len); + } + } + break; + case ST_DEFINEBUTTON2: // has some font ids in the button records + num++; + //fallthrough + case ST_DEFINEBUTTON: { + swf_GetU16(tag); //button id + if(num>1) + { + int offset; + swf_GetU8(tag); //flag + offset = swf_GetU16(tag); //offset + } + while(1) + { + U16 charid; + if(!swf_GetU8(tag)) //flags + break; + callback(tag, tag->pos + base, callback_data); + swf_GetU16(tag); //char + swf_GetU16(tag); //layer + swf_ResetReadBits(tag); + swf_GetMatrix(tag, NULL); + if(num>1) { + swf_ResetReadBits(tag); + swf_GetCXForm(tag, NULL, 1); + } + } + // ... + } + break; + case ST_DEFINEEDITTEXT: { + U8 flags1,flags2; + swf_GetU16(tag); //id + swf_GetRect(tag, NULL); //bounding box + swf_ResetReadBits(tag); + flags1 = swf_GetU8(tag); + flags2 = swf_GetU8(tag); + if(flags1 & 1) + callback(tag, tag->pos + base, callback_data); + } + break; + case ST_DEFINETEXT2: + num ++; + case ST_DEFINETEXT: { + int glyphbits, advancebits; + int id; + id = swf_GetU16(tag); //id + swf_GetRect(tag, NULL); //bounding box + swf_ResetReadBits(tag); + swf_GetMatrix(tag, NULL); //matrix + swf_ResetReadBits(tag); + glyphbits = swf_GetU8(tag); //glyphbits + advancebits = swf_GetU8(tag); //advancebits + while(1) { + U16 flags; + swf_ResetReadBits(tag); + flags = swf_GetBits(tag, 8); + if(!flags) break; + if(flags & 128) // text style record + { + swf_ResetReadBits(tag); + if(flags & 8) { // hasfont + callback(tag, tag->pos + base, callback_data); + id = swf_GetU16(tag); + } + if(flags & 4) { // hascolor + if(num==1) swf_GetRGB(tag, NULL); + else swf_GetRGBA(tag, NULL); + } + if(flags & 2) { //has x offset + swf_ResetReadBits(tag); + swf_GetU16(tag); + } + if(flags & 1) { //has y offset + swf_ResetReadBits(tag); + swf_GetU16(tag); + } + if(flags & 8) { //has height + swf_ResetReadBits(tag); + swf_GetU16(tag); + } + } else { // glyph record + int t; + swf_ResetReadBits(tag); + for(t=0;tpos + base, callback_data); + break; + + case ST_DEFINESHAPE3: // these thingies might have bitmap ids in their fillstyles + num++; //fallthrough + case ST_DEFINESHAPE2: + num++; //fallthrough + case ST_DEFINESHAPE: { + int fillbits; + int linebits; + int id; + id = swf_GetU16(tag); // id; + swf_GetRect(tag, NULL); // bounds + + enumerateUsedIDs_styles(tag, callback, callback_data, num); + fillbits = swf_GetBits(tag, 4); + linebits = swf_GetBits(tag, 4); + swf_ResetReadBits(tag); + while(1) { + int flags; + flags = swf_GetBits(tag, 1); + if(!flags) { //style change + flags = swf_GetBits(tag, 5); + if(!flags) + break; + if(flags&1) { //move + int n = swf_GetBits(tag, 5); + swf_GetBits(tag, n); //x + swf_GetBits(tag, n); //y + } + if(flags&2) { //fill0 + swf_GetBits(tag, fillbits); + } + if(flags&4) { //fill1 + swf_GetBits(tag, fillbits); + } + if(flags&8) { //linestyle + swf_GetBits(tag, linebits); + } + if(flags&16) { + enumerateUsedIDs_styles(tag, callback, callback_data, num); + fillbits = swf_GetBits(tag, 4); + linebits = swf_GetBits(tag, 4); + } + } else { + flags = swf_GetBits(tag, 1); + if(flags) { //straight edge + int n = swf_GetBits(tag, 4) + 2; + if(swf_GetBits(tag, 1)) { //line flag + swf_GetBits(tag, n); //delta x + swf_GetBits(tag, n); //delta y + } else { + int v=swf_GetBits(tag, 1); + swf_GetBits(tag, n); //vert/horz + } + } else { //curved edge + int n = swf_GetBits(tag, 4) + 2; + swf_GetBits(tag, n); + swf_GetBits(tag, n); + swf_GetBits(tag, n); + swf_GetBits(tag, n); + } + } + } + } + break; + default: + break; + } +} + +void callbackCount(TAG * t,int pos, void*ptr) +{ + (*(int*)ptr)++; +} + +void callbackFillin(TAG * t,int pos, void*ptr) +{ + **(int**)ptr = pos; + (*(int**)ptr)++; +} + +int swf_GetNumUsedIDs(TAG * t) +{ + int num = 0; + enumerateUsedIDs(t, 0, callbackCount, &num); + return num; +} + +void swf_GetUsedIDs(TAG * t, int * positions) +{ + int * ptr = positions; + enumerateUsedIDs(t, 0, callbackFillin, &ptr); +} +