X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fmodules%2Fswfshape.c;h=7bb64248d0d2d782b52fd57488c227edad1d41b9;hb=3ef17c4cee41231e1eed731c08381d3ddf0c8d1a;hp=187047b7ebf74f1f429893641257e0233d1ad3bd;hpb=4ac2bb486e0cf7784f7334e955d0a17bc1df41c2;p=swftools.git diff --git a/lib/modules/swfshape.c b/lib/modules/swfshape.c index 187047b..7bb6424 100644 --- a/lib/modules/swfshape.c +++ b/lib/modules/swfshape.c @@ -418,8 +418,8 @@ int swf_ShapeSetLine(TAG * t,SHAPE * s,S32 x,S32 y) b = swf_CountBits(y,b); if (b<2) b=2; if(b >= 18) { - if(b >= 18 + 4) { - /* do not split into more than 16 segments. If the line is *that* long, something's broken */ + if(b >= 18 + 6) { + /* do not split into more than 64 segments. If the line is *that* long, something's broken */ fprintf(stderr, "Warning: Line to %.2f,%.2f is too long\n", (double)x,(double)y); return -1; } else { @@ -506,7 +506,7 @@ 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 parseFillStyleArray(TAG*tag, SHAPE2*shape) +static int parseFillStyleArray(TAG*tag, SHAPE2*shape) { U16 count; int t; @@ -520,6 +520,8 @@ static void parseFillStyleArray(TAG*tag, SHAPE2*shape) num = 2; else if(tag->id == ST_DEFINESHAPE3) num = 3; + else if(tag->id == ST_DEFINESHAPE4) + num = 4; count = swf_GetU8(tag); if(count == 0xff && num>1) // defineshape2,3 only @@ -538,20 +540,22 @@ static void parseFillStyleArray(TAG*tag, SHAPE2*shape) shape->fillstyles[t].type = type; if(type == 0) { /* plain color */ - if(num == 3) + if(num >= 3) swf_GetRGBA(tag, &dest->color); else swf_GetRGB(tag, &dest->color); } - else if(type == 0x10 || type == 0x12) + 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) + else if(type == 0x40 || type == 0x41 || type == 0x42 || type == 0x43) { /* bitmap fill */ swf_ResetReadBits(tag); @@ -578,13 +582,24 @@ static void parseFillStyleArray(TAG*tag, SHAPE2*shape) for(t=linestylestart;tnumlinestyles;t++) { shape->linestyles[t].width = swf_GetU16(tag); - if(num == 3) + + if(num >= 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"); + return 0; + } + } + + if(num >= 3) swf_GetRGBA(tag, &shape->linestyles[t].color); else swf_GetRGB(tag, &shape->linestyles[t].color); } } - return; + return 1; } @@ -635,7 +650,8 @@ static SHAPELINE* swf_ParseShapeData(U8*data, int bits, int fillbits, int linebi } else { linestyleadd = shape2->numlinestyles; fillstyleadd = shape2->numfillstyles; - parseFillStyleArray(tag, shape2); + if(!parseFillStyleArray(tag, shape2)) + return 0; } fillbits = swf_GetBits(tag, 4); linebits = swf_GetBits(tag, 4); @@ -910,6 +926,7 @@ void swf_Shape2ToShape(SHAPE2*shape2, SHAPE*shape) swf_ShapeSetEnd(tag); shape->data = tag->data; shape->bitlen = tag->len*8; + free(tag); } void swf_SetShape2(TAG*tag, SHAPE2*shape2) @@ -938,6 +955,8 @@ void swf_ParseDefineShape(TAG*tag, SHAPE2*shape) num = 2; else if(tag->id == ST_DEFINESHAPE3) num = 3; + else if(tag->id == ST_DEFINESHAPE4) + num = 4; else { fprintf(stderr, "parseDefineShape must be called with a shape tag"); } @@ -947,8 +966,16 @@ void swf_ParseDefineShape(TAG*tag, SHAPE2*shape) memset(shape, 0, sizeof(SHAPE2)); shape->bbox = rfx_alloc(sizeof(SRECT)); swf_GetRect(tag, shape->bbox); + if(num>=4) { + SRECT r2; + swf_ResetReadBits(tag); + swf_GetRect(tag, &r2); // edge bounds + U8 flags = swf_GetU8(tag); // flags, &1: contains scaling stroke, &2: contains non-scaling stroke + } - parseFillStyleArray(tag, shape); + if(!parseFillStyleArray(tag, shape)) { + return; + } swf_ResetReadBits(tag); fill = (U16)swf_GetBits(tag,4); @@ -960,6 +987,13 @@ void swf_ParseDefineShape(TAG*tag, SHAPE2*shape) l = shape->lines; } +static void free_lines(SHAPELINE* lines) +{ + if (lines->next) + free_lines(lines->next); + free(lines); +} + void swf_RecodeShapeData(U8*data, int bitlen, int in_bits_fill, int in_bits_line, U8**destdata, U32*destbitlen, int out_bits_fill, int out_bits_line) { @@ -983,6 +1017,7 @@ void swf_RecodeShapeData(U8*data, int bitlen, int in_bits_fill, int in_bits_line swf_Shape2ToShape(&s2,&s); + free_lines(s2.lines); free(s2.fillstyles); free(s2.linestyles); free(s.fillstyle.data);