Copyright (c) 2000, 2001 Rainer Böhme <rfxswf@reflex-studio.de>
- This file is distributed under the GPL, see file COPYING for details
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
-*/
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
// Matrix & Math tools for SWF files
case ST_DEFINETEXT2:
case ST_DEFINESOUND:
case ST_DEFINESPRITE:
+ case ST_DEFINEMOVIE:
case ST_DEFINEVIDEOSTREAM:
+ case ST_VIDEOFRAME: //pseudodefine
case ST_NAMECHARACTER: //pseudodefine
id = swf_GetU16(t);
break;
return id;
}
+SRECT swf_GetDefineBBox(TAG * t)
+{
+ U32 oldTagPos;
+ U16 id = 0;
+ SRECT b1,b2;
+
+ oldTagPos = swf_GetTagPos(t);
+ swf_SetTagPos(t,0);
+
+ swf_GetRect(0, &b1);
+
+ switch (swf_GetTagID(t))
+ { case ST_DEFINESHAPE:
+ case ST_DEFINESHAPE2:
+ case ST_DEFINESHAPE3:
+ case ST_DEFINEEDITTEXT:
+ case ST_DEFINEBUTTON:
+ case ST_DEFINEBUTTON2:
+ case ST_DEFINETEXT:
+ case ST_DEFINETEXT2:
+ case ST_DEFINEVIDEOSTREAM:
+ id = swf_GetU16(t);
+ swf_GetRect(t, &b1);
+ break;
+ case ST_DEFINEMORPHSHAPE:
+ id = swf_GetU16(t);
+ swf_GetRect(t, &b1);
+ swf_GetRect(t, &b2);
+ swf_ExpandRect2(&b1, &b2);
+ break;
+ case ST_DEFINEBITSLOSSLESS:
+ case ST_DEFINEBITSLOSSLESS2:
+ case ST_DEFINEBITS:
+ case ST_DEFINEBITSJPEG2:
+ case ST_DEFINEBITSJPEG3:
+ // FIXME
+ break;
+ }
+
+ swf_SetTagPos(t,oldTagPos);
+
+ return b1;
+}
+
U16 swf_GetPlaceID(TAG * t)
// up to SWF 4.0
{ U32 oldTagPos;
ST_DEFINEBUTTONSOUND,
ST_NAMECHARACTER,
ST_DOINITACTION,
+ ST_VIDEOFRAME,
-1
};
return 0;
}
-U16 swf_GetDepth(TAG * t)
-// up to SWF 4.0
+int swf_GetDepth(TAG * t)
{
- U16 depth = 0;
+ int depth = -1;
U32 oldTagPos;
oldTagPos = swf_GetTagPos(t);
swf_SetTagPos(t,0);
{ U8 flags = swf_GetU8(t);
depth = swf_GetU16(t);
} break;
+ case ST_SETTABINDEX:
+ {
+ depth = swf_GetU16(t);
+ }
}
swf_SetTagPos(t,oldTagPos);
return depth;
}
+void swf_SetDepth(TAG * t, U16 depth)
+{
+ switch (swf_GetTagID(t))
+ { case ST_PLACEOBJECT:
+ case ST_REMOVEOBJECT:
+ PUT16(t->data, depth);
+ break;
+ case ST_REMOVEOBJECT2:
+ PUT16(t->data, depth);
+ break;
+ case ST_PLACEOBJECT2:
+ PUT16(&t->data[1], depth);
+ break;
+ case ST_SETTABINDEX:
+ PUT16(t->data, depth);
+ break;
+ default:
+ fprintf(stderr, "rfxswf: Error: tag %d has no depth\n", t->id);
+ }
+}
+
char* swf_GetName(TAG * t)
{
char* name = 0;
swf_GetCXForm(t, &c, 1);
if(flags&PF_RATIO)
swf_GetU16(t);
+ if(flags&PF_CLIPACTION)
+ swf_GetU16(t);
if(flags&PF_NAME) {
swf_ResetReadBits(t);
name = &t->data[swf_GetTagPos(t)];
case ST_FREECHARACTER: /* unusual tags, which all start with an ID */
case ST_NAMECHARACTER:
case ST_GENERATORTEXT:
- case ST_MX3:
callback(tag, tag->pos + base, callback_data);
break;
case ST_PLACEOBJECT:
tag=tag->next;
}
}
-
+
+void swf_RelocateDepth(SWF*swf, char*bitmap)
+{
+ TAG*tag;
+ int nr;
+ tag = swf->firstTag;
+ for(nr=65535;nr>=0;nr--) {
+ if(bitmap[nr] != 0)
+ break;
+ }
+ // now nr is the highest used depth. So we start
+ // assigning depths at nr+1
+ nr++;
+
+ while(tag)
+ {
+ int depth = swf_GetDepth(tag);
+ if(depth>=0) {
+ int newdepth = depth+nr;
+ if(newdepth>65535) {
+ fprintf(stderr, "Couldn't relocate depths: too large values\n");
+ newdepth = 65535;
+ }
+ swf_SetDepth(tag, newdepth);
+ }
+ tag=tag->next;
+ }
+}
+
+TAG* swf_Concatenate (TAG*list1,TAG*list2)
+{
+ TAG*tag=0,*lasttag=0;
+ char bitmap[65536];
+ char depthmap[65536];
+ memset(bitmap, 0, sizeof(bitmap));
+ memset(depthmap, 0, sizeof(depthmap));
+ SWF swf1,swf2;
+ memset(&swf1, 0, sizeof(swf1));
+ memset(&swf2, 0, sizeof(swf2));
+
+ swf1.firstTag = list1;
+ swf_FoldAll(&swf1);
+ swf2.firstTag = list2;
+ swf_FoldAll(&swf2);
+
+ tag = list1;
+ while(tag) {
+ if(!swf_isDefiningTag(tag)) {
+ int id = swf_GetDefineID(tag);
+ bitmap[id] = 1;
+ }
+ if(tag->id == ST_PLACEOBJECT ||
+ tag->id == ST_PLACEOBJECT2) {
+ int depth = swf_GetDepth(tag);
+ depthmap[depth] = 1;
+ }
+ if(tag->id == ST_REMOVEOBJECT ||
+ tag->id == ST_REMOVEOBJECT2) {
+ int depth = swf_GetDepth(tag);
+ depthmap[depth] = 0;
+ }
+ tag = tag->next;
+ lasttag = tag;
+ }
+ swf_Relocate(&swf2, bitmap);
+ swf_RelocateDepth(&swf2, depthmap);
+ lasttag->next = swf2.firstTag;
+ swf2.firstTag->prev = lasttag;
+
+ return swf1.firstTag;
+}