From 6edd030417e792d2325d5d6b89a6495ab8798cba Mon Sep 17 00:00:00 2001 From: kramm Date: Sun, 16 Mar 2008 10:13:32 +0000 Subject: [PATCH] several flash 8 fixes --- lib/modules/swfshape.c | 100 ++++++++++++++------------ lib/modules/swftools.c | 182 +++++++++++++++++++++++++++++------------------- 2 files changed, 166 insertions(+), 116 deletions(-) diff --git a/lib/modules/swfshape.c b/lib/modules/swfshape.c index c5a8835..3163556 100644 --- a/lib/modules/swfshape.c +++ b/lib/modules/swfshape.c @@ -506,6 +506,39 @@ void dummycallback1(TAG*tag, int x, void*y) // from swftools.c: void enumerateUsedIDs_styles(TAG * tag, void (*callback)(TAG*, int, void*), void*callback_data, int num, int morph); +static void parseFillStyle(FILLSTYLE*dest, TAG*tag, int num) +{ + int type = swf_GetU8(tag); //type + dest->type = type; + if(type == 0) { + /* plain color */ + if(num >= 3) + swf_GetRGBA(tag, &dest->color); + else + swf_GetRGB(tag, &dest->color); + } + else if(type == 0x10 || type == 0x11 || type == 0x12 || type == 0x13) + { + /* linear/radial gradient fill */ + swf_ResetReadBits(tag); + swf_GetMatrix(tag, &dest->m); + swf_ResetReadBits(tag); + swf_GetGradient(tag, &dest->gradient, num>=3?1:0); + if(type == 0x13) + swf_GetU16(tag); + } + else if(type == 0x40 || type == 0x41 || type == 0x42 || type == 0x43) + { + /* bitmap fill */ + swf_ResetReadBits(tag); + dest->id_bitmap = swf_GetU16(tag); //id + swf_ResetReadBits(tag); //? + swf_GetMatrix(tag, &dest->m); + } + else { + fprintf(stderr, "rfxswf:swfshape.c Unknown fillstyle:0x%02x in tag %02d\n",type, tag->id); + } +} static int parseFillStyleArray(TAG*tag, SHAPE2*shape) { U16 count; @@ -531,40 +564,8 @@ static int parseFillStyleArray(TAG*tag, SHAPE2*shape) if(shape->numfillstyles) { shape->fillstyles = (FILLSTYLE*)rfx_realloc(shape->fillstyles, sizeof(FILLSTYLE)*shape->numfillstyles); - for(t=fillstylestart;tnumfillstyles;t++) - { - int type; - FILLSTYLE*dest = &shape->fillstyles[t]; - type = swf_GetU8(tag); //type - shape->fillstyles[t].type = type; - if(type == 0) { - /* plain color */ - if(num >= 3) - swf_GetRGBA(tag, &dest->color); - else - swf_GetRGB(tag, &dest->color); - } - else if(type == 0x10 || type == 0x11 || type == 0x12 || type == 0x13) - { - /* linear/radial gradient fill */ - swf_ResetReadBits(tag); - swf_GetMatrix(tag, &dest->m); - swf_ResetReadBits(tag); - swf_GetGradient(tag, &dest->gradient, num>=3?1:0); - if(type == 0x13) - swf_GetU8(tag); - } - else if(type == 0x40 || type == 0x41 || type == 0x42 || type == 0x43) - { - /* bitmap fill */ - swf_ResetReadBits(tag); - dest->id_bitmap = swf_GetU16(tag); //id - swf_ResetReadBits(tag); //? - swf_GetMatrix(tag, &dest->m); - } - else { - fprintf(stderr, "rfxswf:swftools.c Unknown fillstyle:0x%02x\n",type); - } + for(t=fillstylestart;tnumfillstyles;t++) { + parseFillStyle(&shape->fillstyles[t], tag, num); } } @@ -580,22 +581,29 @@ static int parseFillStyleArray(TAG*tag, SHAPE2*shape) "built in" linestyle 0? */ for(t=linestylestart;tnumlinestyles;t++) { + char fill = 0; shape->linestyles[t].width = swf_GetU16(tag); if(num >= 4) { U16 flags = swf_GetU16(tag); - if(flags & 0x2000) + if((flags & 0x30) == 0x20) swf_GetU16(tag); // miter limit - if(flags & 0x0800) { - fprintf(stderr, "Filled strokes parsing not yet supported\n"); - return 0; + if(flags & 0x08) { + fprintf(stderr, "Warning: Filled strokes parsing not yet fully supported\n"); + fill = 1; } } - if(num >= 3) - swf_GetRGBA(tag, &shape->linestyles[t].color); - else - swf_GetRGB(tag, &shape->linestyles[t].color); + if(fill) { + FILLSTYLE f; + parseFillStyle(&f, tag, num); + shape->linestyles[t].color = f.color; + } else { + if(num >= 3) + swf_GetRGBA(tag, &shape->linestyles[t].color); + else + swf_GetRGB(tag, &shape->linestyles[t].color); + } } } return 1; @@ -621,7 +629,7 @@ static SHAPELINE* swf_ParseShapeData(U8*data, int bits, int fillbits, int linebi tag->data = data; tag->len = tag->memsize = (bits+7)/8; tag->pos = 0; - tag->id = version==1?ST_DEFINESHAPE:(version==2?ST_DEFINESHAPE2:ST_DEFINESHAPE3); + tag->id = version==1?ST_DEFINESHAPE:(version==2?ST_DEFINESHAPE2:(version==3?ST_DEFINESHAPE3:ST_DEFINESHAPE4)); lines->next = 0; while(1) { @@ -977,9 +985,11 @@ void swf_ParseDefineShape(TAG*tag, SHAPE2*shape) swf_ResetReadBits(tag); fill = (U16)swf_GetBits(tag,4); line = (U16)swf_GetBits(tag,4); + if(!fill && !line) { + fprintf(stderr, "fill/line bits are both zero\n"); + } - shape->lines = swf_ParseShapeData(&tag->data[tag->pos], (tag->len - tag->pos)*8, fill, line, - tag->id == ST_DEFINESHAPE?1:(tag->id==ST_DEFINESHAPE2?2:3), shape); + shape->lines = swf_ParseShapeData(&tag->data[tag->pos], (tag->len - tag->pos)*8, fill, line, num, shape); l = shape->lines; } diff --git a/lib/modules/swftools.c b/lib/modules/swftools.c index 8ee2001..1b01357 100644 --- a/lib/modules/swftools.c +++ b/lib/modules/swftools.c @@ -461,6 +461,92 @@ void swf_GetMorphGradient(TAG * tag, GRADIENT * gradient1, GRADIENT * gradient2) #define DEBUG_ENUMERATE if(0) //#define DEBUG_ENUMERATE +void enumerateUsedIDs_fillstyle(TAG * tag, int t, void (*callback)(TAG*, int, void*), void*callback_data, int num, int morph) +{ + int type; + type = swf_GetU8(tag); //type + DEBUG_ENUMERATE printf("fill style %d) type=%02x (tagpos=%d)\n", t, type, tag->pos); + if(type == 0) { + RGBA color; + if(num >= 3) + {swf_GetRGBA(tag, &color);if(morph) swf_GetRGBA(tag, NULL);} + else + {swf_GetRGB(tag, &color);if(morph) swf_GetRGB(tag, NULL);} + DEBUG_ENUMERATE printf(" %02x%02x%02x%02x\n", color.r,color.g,color.b,color.a); + } + else if(type == 0x10 || type == 0x12 || type == 0x13) + { + swf_ResetReadBits(tag); + MATRIX m; + swf_GetMatrix(tag, &m); + DEBUG_ENUMERATE swf_DumpMatrix(stdout, &m); + if(morph) { + swf_GetMatrix(tag, &m); + DEBUG_ENUMERATE swf_DumpMatrix(stdout, &m); + } + swf_ResetReadBits(tag); + if(morph) { + swf_GetMorphGradient(tag, NULL, NULL); + if(type == 0x13) { + swf_GetU16(tag); + swf_GetU16(tag); + } + } else { + GRADIENT g; + swf_GetGradient(tag, &g, /*alpha*/ num>=3?1:0); + DEBUG_ENUMERATE swf_DumpGradient(stdout, &g); + if(type == 0x13) + swf_GetU16(tag); + } + } + else if(type == 0x40 || type == 0x41 || type == 0x42 || type == 0x43) + { + swf_ResetReadBits(tag); + 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); + if(morph) + swf_GetMatrix(tag, NULL); + } + else { + fprintf(stderr, "rfxswf:swftools.c Unknown fillstyle:0x%02x in tag %02d\n",type, tag->id); + } +} + +void enumerateUsedIDs_linestyle(TAG * tag, int t, void (*callback)(TAG*, int, void*), void*callback_data, int num, int morph) +{ + U16 width; + RGBA color; + width = swf_GetU16(tag); + char fill=0; + if(morph) + swf_GetU16(tag); + if(num >= 4) { + U16 flags = swf_GetU16(tag); + DEBUG_ENUMERATE printf("line style %d) flags: %08x\n", t, flags); + if((flags & 0x30) == 0x20) { + U16 miter = swf_GetU16(tag); // miter limit + DEBUG_ENUMERATE printf("line style %d) miter join: %08x\n", t, miter); + } + if(flags & 0x08) { + fill = 1; + } + } + if(!fill) { + if(num >= 3) + {swf_GetRGBA(tag, &color);if(morph) swf_GetRGBA(tag, NULL);} + else + {swf_GetRGB(tag, &color);if(morph) swf_GetRGB(tag, NULL);} + } else { + enumerateUsedIDs_fillstyle(tag, t, callback, callback_data, num, morph); + } + DEBUG_ENUMERATE printf("line style %d) width=%.2f color=%02x%02x%02x%02x \n", t, width/20.0, color.r,color.g,color.b,color.a); +} + void enumerateUsedIDs_styles(TAG * tag, void (*callback)(TAG*, int, void*), void*callback_data, int num, int morph) { U16 count; @@ -472,50 +558,7 @@ void enumerateUsedIDs_styles(TAG * tag, void (*callback)(TAG*, int, void*), void DEBUG_ENUMERATE printf("%d fill styles\n", count); for(t=0;tpos); - if(type == 0) { - if(num >= 3) - {swf_GetRGBA(tag, NULL);if(morph) swf_GetRGBA(tag, NULL);} - else - {swf_GetRGB(tag, NULL);if(morph) swf_GetRGB(tag, NULL);} - } - else if(type == 0x10 || type == 0x12 || type == 0x13) - { - swf_ResetReadBits(tag); - MATRIX m; - swf_GetMatrix(tag, &m); - DEBUG_ENUMERATE swf_DumpMatrix(stdout, &m); - if(morph) - swf_GetMatrix(tag, NULL); - swf_ResetReadBits(tag); - if(morph) - swf_GetMorphGradient(tag, NULL, NULL); - else { - GRADIENT g; - swf_GetGradient(tag, &g, /*alpha*/ num>=3?1:0); - DEBUG_ENUMERATE swf_DumpGradient(stdout, &g); - if(type == 0x13) - swf_GetU16(tag); - } - } - else if(type == 0x40 || type == 0x41 || type == 0x42 || type == 0x43) - { - swf_ResetReadBits(tag); - 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); - if(morph) - swf_GetMatrix(tag, NULL); - } - else { - fprintf(stderr, "rfxswf:swftools.c Unknown fillstyle:0x%02x in tag %02x\n",type, tag->id); - } + enumerateUsedIDs_fillstyle(tag, t, callback, callback_data, num, morph); } swf_ResetReadBits(tag); count = swf_GetU8(tag); // line style array @@ -524,24 +567,7 @@ void enumerateUsedIDs_styles(TAG * tag, void (*callback)(TAG*, int, void*), void DEBUG_ENUMERATE printf("%d line styles\n", count); for(t=0;t= 4) { - U16 flags = swf_GetU16(tag); - if(flags & 0x2000) - swf_GetU16(tag); // miter limit - if(flags & 0x0800) { - fprintf(stderr, "Filled strokes parsing not yet supported\n"); - } - } - if(num >= 3) - {swf_GetRGBA(tag, &color);if(morph) swf_GetRGBA(tag, NULL);} - else - {swf_GetRGB(tag, &color);if(morph) swf_GetRGB(tag, NULL);} - DEBUG_ENUMERATE printf("line style %d: %02x%02x%02x%02x \n", t, color.r,color.g,color.b,color.a); + enumerateUsedIDs_linestyle(tag, t, callback, callback_data, num, morph); } } @@ -676,7 +702,8 @@ void enumerateUsedIDs(TAG * tag, int base, void (*callback)(TAG*, int, void*), v } while(1) { - if(!swf_GetU8(tag)) //flags + U8 flags = swf_GetU8(tag); + if(!flags) //flags break; callback(tag, tag->pos + base, callback_data); swf_GetU16(tag); //char @@ -687,6 +714,16 @@ void enumerateUsedIDs(TAG * tag, int base, void (*callback)(TAG*, int, void*), v swf_ResetReadBits(tag); swf_GetCXForm(tag, NULL, 1); } + if(flags&0x10) { + U8 num = swf_GetU8(tag); + int t; + for(t=0;t