X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Frfxswf.c;h=aeb0733d5e56d593f15a640033511f439fa99295;hb=b9c0bd0865006169c32be33c4ebb3f6d98f4a428;hp=1460c35d4d5f1e427f3288cc24ca939a4b22f0a7;hpb=6cfa6f2326b39d3dee66a27cb77ad5e8fab021a1;p=swftools.git diff --git a/lib/rfxswf.c b/lib/rfxswf.c index 1460c35..aeb0733 100644 --- a/lib/rfxswf.c +++ b/lib/rfxswf.c @@ -139,7 +139,7 @@ int swf_GetBlock(TAG * t,U8 * b,int l) return l; } -int swf_SetBlock(TAG * t,U8 * b,int l) +int swf_SetBlock(TAG * t,const U8 * b,int l) // Appends Block to the end of Tagdata, returns size { U32 newlen = t->len + l; swf_ResetWriteBits(t); @@ -261,7 +261,7 @@ double swf_GetFixed(TAG * t) } void swf_SetFixed(TAG * t, double f) { - U16 fr = (U16)(f-(int)f)*65536; + U16 fr = (U16)((f-(int)f)*65536); swf_SetU16(t, fr); swf_SetU16(t, (U16)f - (f<0 && fr!=0)); } @@ -273,7 +273,7 @@ float swf_GetFixed8(TAG * t) } void swf_SetFixed8(TAG * t, float f) { - U8 fr = (U8)(f-(int)f)*256; + U8 fr = (U8)((f-(int)f)*256); swf_SetU8(t, fr); swf_SetU8(t, (U8)f - (f<0 && fr!=0)); } @@ -454,6 +454,20 @@ int swf_SetRect(TAG * t,SRECT * r) return 0; } +SRECT swf_ClipRect(SRECT border, SRECT r) +{ + if(r.xmax > border.xmax) r.xmax = border.xmax; + if(r.ymax > border.ymax) r.ymax = border.ymax; + if(r.xmax < border.xmin) r.xmax = border.xmin; + if(r.ymax < border.ymin) r.ymax = border.ymin; + + if(r.xmin > border.xmax) r.xmin = border.xmax; + if(r.ymin > border.ymax) r.ymin = border.ymax; + if(r.xmin < border.xmin) r.xmin = border.xmin; + if(r.ymin < border.ymin) r.ymin = border.ymin; + return r; +} + void swf_ExpandRect(SRECT*src, SPOINT add) { if((src->xmin | src->ymin | src->xmax | src->ymax)==0) { @@ -849,15 +863,18 @@ TAG* swf_CopyTag(TAG*tag, TAG*to_copy) return tag; } -int swf_DeleteTag(TAG * t) -{ if (!t) return -1; +TAG* swf_DeleteTag(SWF*swf, TAG * t) +{ + TAG*next = t->next; + if (swf && swf->firstTag==t) + swf->firstTag = t->next; if (t->prev) t->prev->next = t->next; if (t->next) t->next->prev = t->prev; if (t->data) rfx_free(t->data); rfx_free(t); - return 0; + return next; } TAG * swf_ReadTag(reader_t*reader, TAG * prev) @@ -924,7 +941,12 @@ int swf_WriteTag2(writer_t*writer, TAG * t) t->id!=ST_DEFINEBITSJPEG&&t->id!=ST_DEFINEBITSJPEG2&&t->id!=ST_DEFINEBITSJPEG3); if (writer) - { if (short_tag) + { +#ifdef MEASURE + int oldpos = writer->pos; +#endif + + if (short_tag) { raw[0] = SWAP16(len|((t->id&0x3ff)<<6)); if (writer->write(writer,raw,2)!=2) { @@ -967,6 +989,11 @@ int swf_WriteTag2(writer_t*writer, TAG * t) #ifdef DEBUG_RFXSWF else if (t->len) fprintf(stderr,"WriteTag(): Tag Data Error, id=%i\n",t->id); #endif + +#ifdef MEASURE + writer->flush(writer); + printf("TAG %s costs %d bytes\n", swf_TagGetName(t), writer->pos-oldpos); +#endif } return t->len+(short_tag?2:6); @@ -1115,7 +1142,7 @@ void swf_FoldSprite(TAG * t) if(t->id == ST_END) level--; t = swf_NextTag(t); - swf_DeleteTag(tmp); + swf_DeleteTag(0, tmp); } while (t && level); if(level) @@ -1247,7 +1274,13 @@ int swf_ReadSWF2(reader_t*reader, SWF * swf) // Reads SWF to memory (malloc'ed /* read tags and connect to list */ t = &t1; - while (t) t = swf_ReadTag(reader,t); + while (t) { + t = swf_ReadTag(reader,t); + if(t && t->id == ST_FILEATTRIBUTES) { + swf->fileAttributes = swf_GetU32(t); + swf_ResetReadBits(t); + } + } swf->firstTag = t1.next; t1.next->prev = NULL; } @@ -1262,6 +1295,69 @@ int swf_ReadSWF(int handle, SWF * swf) return swf_ReadSWF2(&reader, swf); } +int no_extra_tags = 0; + +int WriteExtraTags(SWF*swf, writer_t*writer) +{ + TAG*t = swf->firstTag; + TAG* has_fileattributes=0; + int has_scenedescription=0; + int has_version_8_action=0; + int has_version_9_action=0; + int len = 0; + while(t) { + if(t->id == ST_FILEATTRIBUTES) + has_fileattributes = t; + if(t->id == ST_SCENEDESCRIPTION) + has_scenedescription = 1; + if(t->id == ST_DOABC) + has_version_9_action=1; + /* FIXME: this doesn't yet find actionscript in buttons */ + if(t->id == ST_DOACTION || t->id == ST_DOINITACTION) + has_version_8_action=1; + if(t->id == ST_PLACEOBJECT2 && t->len && (t->data[0]&0x80)) + has_version_8_action=1; + t = t->next; + } + if(has_version_8_action && has_version_9_action) { + fprintf(stderr, "Warning: File contains both flash 8 and flash 9 actionscript\n"); + } + + if(swf->fileVersion >= 9) { + if(!has_fileattributes) { + U32 flags = swf->fileAttributes|0x08; // 16 = has symbolclass tag | 8 = actionscript3 | 1 = usenetwork + if(has_version_8_action && !has_version_9_action) + flags &= ~0x08; + TAG*fileattrib = swf_InsertTag(0, ST_FILEATTRIBUTES); + swf_SetU32(fileattrib, flags); + if(writer) { + if(swf_WriteTag2(writer, fileattrib)<0) + return -1; + } else { + len += swf_WriteTag(-1,fileattrib); + } + swf_DeleteTag(0, fileattrib); + } else { + if(swf_WriteTag2(writer, has_fileattributes)<0) + return -1; + } + if(!has_scenedescription) { + TAG*scene = swf_InsertTag(0, ST_SCENEDESCRIPTION); + swf_SetU16(scene, 1); + swf_SetString(scene, (U8*)"Scene 1"); + swf_SetU8(scene, 0); + if(writer) { + if(swf_WriteTag2(writer, scene)<0) + return -1; + } else { + len += swf_WriteTag(-1,scene); + } + swf_DeleteTag(0, scene); + } + } + return len; +} + int swf_WriteSWF2(writer_t*writer, SWF * swf) // Writes SWF to file, returns length or <0 if fails { U32 len; TAG * t; @@ -1269,48 +1365,14 @@ int swf_WriteSWF2(writer_t*writer, SWF * swf) // Writes SWF to file, return writer_t zwriter; int fileSize = 0; int inSprite = 0; - int writer_lastpos = 0; int ret; + writer_t*original_writer = writer; + int writer_lastpos = 0; if (!swf) return -1; if (!writer) return -1; // the caller should provide a nullwriter, not 0, for querying SWF size - if(writer) writer_lastpos = writer->pos; - - // Insert REFLEX Tag - -#ifdef INSERT_RFX_TAG - - if ((swf->firstTag && swf->firstTag->id != ST_REFLEX) && - (!swf->firstTag->next || swf->firstTag->next->id != ST_REFLEX)) - { - swf_SetBlock(swf_InsertTagBefore(swf, swf->firstTag,ST_REFLEX),(U8*)"rfx",3); - } - -#endif // INSERT_RFX_TAG - - if(swf->fileVersion >= 9) { - if ((!swf->firstTag || swf->firstTag->id != ST_SCENEDESCRIPTION) && - (!swf->firstTag || - !swf->firstTag->next || swf->firstTag->next->id != ST_SCENEDESCRIPTION) && - (!swf->firstTag || - !swf->firstTag->next || - !swf->firstTag->next->next || swf->firstTag->next->next->id != ST_SCENEDESCRIPTION)) - { - TAG*scene = swf_InsertTagBefore(swf, swf->firstTag,ST_SCENEDESCRIPTION); - swf_SetU16(scene, 1); - swf_SetString(scene, (U8*)"Scene 1"); - swf_SetU8(scene, 0); - } - } - - if(swf->fileVersion >= 9) { - if (swf->firstTag && swf->firstTag->id != ST_FILEATTRIBUTES) - { - U32 flags = 0x8; // | 128 = usenetwork, | 16 = Actionscript3 | 8 = hasmetadata - swf_SetU32(swf_InsertTagBefore(swf, swf->firstTag,ST_FILEATTRIBUTES),flags); - } - } + if(original_writer) writer_lastpos = original_writer->pos; // Count Frames + File Size @@ -1318,6 +1380,7 @@ int swf_WriteSWF2(writer_t*writer, SWF * swf) // Writes SWF to file, return t = swf->firstTag; frameCount = 0; + len += WriteExtraTags(swf, 0); while(t) { len += swf_WriteTag(-1,t); if(t->id == ST_DEFINESPRITE && !swf_IsFolded(t)) inSprite++; @@ -1399,15 +1462,22 @@ int swf_WriteSWF2(writer_t*writer, SWF * swf) // Writes SWF to file, return return -1; } + if(!no_extra_tags) { + WriteExtraTags(swf, writer); + } t = swf->firstTag; - while (t) - { if (swf_WriteTag2(writer, t)<0) return -1; - t = swf_NextTag(t); + + while (t) { + if(no_extra_tags || t->id != ST_FILEATTRIBUTES) { + if(swf_WriteTag2(writer, t)<0) + return -1; + } + t = t->next; } if(swf->compressed==1 || (swf->compressed==0 && swf->fileVersion>=6) || swf->compressed==8) { if(swf->compressed != 8) { zwriter.finish(&zwriter); - return writer->pos - writer_lastpos; + return original_writer->pos - writer_lastpos; } return (int)fileSize; } else {