X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fmodules%2Fswfshape.c;h=c5a8835830d6abedc239d96527c9158d86bd7283;hb=0784a8a882e7b98299fb6a90f0f9a7ebb322562b;hp=6ef8aa2125f80ce32c9eece2783af2360af28857;hpb=f1d2b6c34d9ecedbd0766f16272162b66196142b;p=swftools.git diff --git a/lib/modules/swfshape.c b/lib/modules/swfshape.c index 6ef8aa2..c5a8835 100644 --- a/lib/modules/swfshape.c +++ b/lib/modules/swfshape.c @@ -203,7 +203,7 @@ int swf_SetShapeStyleCount(TAG * t,U16 n) return 3; } else - { swf_SetU8(t,n); + { swf_SetU8(t,(U8)n); return 1; } } @@ -277,9 +277,9 @@ int swf_ShapeAddFillStyle(SHAPE * s,U8 type,MATRIX * m,RGBA * color,U16 id_bitma // handle memory if (s->fillstyle.data) - { FILLSTYLE * new = (FILLSTYLE *)rfx_realloc(s->fillstyle.data,(s->fillstyle.n+1)*sizeof(FILLSTYLE)); - if (!new) return -1; - s->fillstyle.data = new; + { FILLSTYLE * xnew = (FILLSTYLE *)rfx_realloc(s->fillstyle.data,(s->fillstyle.n+1)*sizeof(FILLSTYLE)); + if (!xnew) return -1; + s->fillstyle.data = xnew; } else { s->fillstyle.data = (FILLSTYLE *)rfx_alloc(sizeof(FILLSTYLE)); @@ -323,9 +323,9 @@ int swf_ShapeAddLineStyle(SHAPE * s,U16 width,RGBA * color) def.r = def.g = def.b = 0; } if (s->linestyle.data) - { LINESTYLE * new = (LINESTYLE *)rfx_realloc(s->linestyle.data,(s->linestyle.n+1)*sizeof(LINESTYLE)); - if (!new) return -1; - s->linestyle.data = new; + { LINESTYLE * xnew = (LINESTYLE *)rfx_realloc(s->linestyle.data,(s->linestyle.n+1)*sizeof(LINESTYLE)); + if (!xnew) return -1; + s->linestyle.data = xnew; } else { s->linestyle.data = (LINESTYLE *)rfx_alloc(sizeof(LINESTYLE)); @@ -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 @@ -527,31 +529,32 @@ static void parseFillStyleArray(TAG*tag, SHAPE2*shape) shape->numfillstyles += count; if(shape->numfillstyles) { - shape->fillstyles = rfx_realloc(shape->fillstyles, sizeof(FILLSTYLE)*shape->numfillstyles); + shape->fillstyles = (FILLSTYLE*)rfx_realloc(shape->fillstyles, sizeof(FILLSTYLE)*shape->numfillstyles); for(t=fillstylestart;tnumfillstyles;t++) { int type; - U8*pos; FILLSTYLE*dest = &shape->fillstyles[t]; type = swf_GetU8(tag); //type 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); @@ -572,19 +575,30 @@ static void parseFillStyleArray(TAG*tag, SHAPE2*shape) shape->numlinestyles += count; if(count) { - shape->linestyles = rfx_realloc(shape->linestyles, sizeof(LINESTYLE)*shape->numlinestyles); + shape->linestyles = (LINESTYLE*)rfx_realloc(shape->linestyles, sizeof(LINESTYLE)*shape->numlinestyles); /* TODO: should we start with 1 and insert a correct definition of the "built in" linestyle 0? */ 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 +649,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); @@ -749,32 +764,41 @@ SRECT swf_GetShapeBoundingBox(SHAPE2*shape2) void swf_Shape2Free(SHAPE2 * s) { SHAPELINE*line = s->lines; + s->lines = 0; while(line) { SHAPELINE*next = line->next; + line->next = 0; rfx_free(line); line = next; } - if(s->linestyles) + + if(s->linestyles) { rfx_free(s->linestyles); - if(s->fillstyles) + s->linestyles = 0; + } + if(s->fillstyles) { rfx_free(s->fillstyles); - if(s->bbox) + s->fillstyles = 0; + } + if(s->bbox) { rfx_free(s->bbox); + s->bbox = 0; + } } SHAPE2* swf_Shape2Clone(SHAPE2 * s) { SHAPELINE*line = s->lines; SHAPELINE*prev = 0; - SHAPE2*s2 = rfx_alloc(sizeof(SHAPE2)); + SHAPE2*s2 = (SHAPE2*)rfx_alloc(sizeof(SHAPE2)); memcpy(s2,s,sizeof(SHAPE2)); - s2->linestyles = rfx_alloc(sizeof(LINESTYLE)*s->numlinestyles); + s2->linestyles = (LINESTYLE*)rfx_alloc(sizeof(LINESTYLE)*s->numlinestyles); memcpy(s2->linestyles, s->linestyles, sizeof(LINESTYLE)*s->numlinestyles); - s2->fillstyles = rfx_alloc(sizeof(FILLSTYLE)*s->numfillstyles); + s2->fillstyles = (FILLSTYLE*)rfx_alloc(sizeof(FILLSTYLE)*s->numfillstyles); memcpy(s2->fillstyles, s->fillstyles, sizeof(FILLSTYLE)*s->numfillstyles); while(line) { - SHAPELINE*line2 = rfx_alloc(sizeof(SHAPELINE)); + SHAPELINE*line2 = (SHAPELINE*)rfx_alloc(sizeof(SHAPELINE)); memcpy(line2, line, sizeof(SHAPELINE)); line2->next = 0; if(prev) @@ -785,7 +809,7 @@ SHAPE2* swf_Shape2Clone(SHAPE2 * s) line = line->next; } if(s->bbox) { - s2->bbox = rfx_alloc(sizeof(SRECT)); + s2->bbox = (SRECT*)rfx_alloc(sizeof(SRECT)); memcpy(s2->bbox, s->bbox, sizeof(SRECT)); } return s2; @@ -852,7 +876,7 @@ void swf_ShapeSetBitmapRect(TAG*tag, U16 gfxid, int width, int height) void swf_Shape2ToShape(SHAPE2*shape2, SHAPE*shape) { TAG*tag = swf_InsertTag(0,0); - SHAPELINE*l,*next; + SHAPELINE*l; int newx=0,newy=0,lastx=0,lasty=0,oldls=0,oldfs0=0,oldfs1=0; memset(shape, 0, sizeof(SHAPE)); @@ -901,6 +925,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) @@ -920,8 +945,6 @@ void swf_ParseDefineShape(TAG*tag, SHAPE2*shape) { int num = 0, id; U16 fill,line; - SRECT r; - SRECT r2; SHAPELINE*l; if(tag->id == ST_DEFINESHAPE) num = 1; @@ -929,6 +952,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"); } @@ -936,10 +961,18 @@ void swf_ParseDefineShape(TAG*tag, SHAPE2*shape) id = swf_GetU16(tag); //id memset(shape, 0, sizeof(SHAPE2)); - shape->bbox = rfx_alloc(sizeof(SRECT)); + shape->bbox = (SRECT*)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); @@ -951,6 +984,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) { @@ -961,8 +1001,8 @@ void swf_RecodeShapeData(U8*data, int bitlen, int in_bits_fill, int in_bits_line s2.lines = swf_ParseShapeData(data, bitlen, in_bits_fill, in_bits_line, 1, 0); s2.numfillstyles = out_bits_fill?1<<(out_bits_fill-1):0; s2.numlinestyles = out_bits_line?1<<(out_bits_line-1):0; - s2.fillstyles = rfx_calloc(sizeof(FILLSTYLE)*s2.numfillstyles); - s2.linestyles = rfx_calloc(sizeof(LINESTYLE)*s2.numlinestyles); + s2.fillstyles = (FILLSTYLE*)rfx_calloc(sizeof(FILLSTYLE)*s2.numfillstyles); + s2.linestyles = (LINESTYLE*)rfx_calloc(sizeof(LINESTYLE)*s2.numlinestyles); line = s2.lines; while(line) { @@ -974,6 +1014,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);