Added sprite folding
[swftools.git] / lib / rfxswf.c
index 7754ba9..9a568fd 100644 (file)
@@ -545,12 +545,15 @@ TAG * RFXSWF_ReadTag(int handle,TAG * prev)
   int id;
 
   if (read(handle,&raw,2)!=2) return NULL;
+  raw = SWAP16(raw);
 
   len = raw&0x3f;
   id  = raw>>6;
 
   if (len==0x3f)
-  { if (read(handle,&len,4)!=4) return NULL;
+  {
+      if (read(handle,&len,4)!=4) return NULL;
+      len = SWAP32(len);
   }
 
   if (id==ST_DEFINESPRITE) len = 2*sizeof(U16);
@@ -610,7 +613,7 @@ int RFXSWF_WriteTag(int handle,TAG * t)
 
   if (handle>=0)
   { if (short_tag)
-    { raw[0] = len|((t->id&0x3ff)<<6);
+    { raw[0] = SWAP16(len|((t->id&0x3ff)<<6));
       if (write(handle,raw,2)!=2)
       {
         #ifdef DEBUG_RFXSWF
@@ -620,13 +623,21 @@ int RFXSWF_WriteTag(int handle,TAG * t)
       }
     }
     else
-    { raw[0] = (t->id<<6)|0x3f;
-      raw[1] = (U16)(len&0xffff);
-      raw[2] = (U16)(len>>16);
-      if (write(handle,raw,6)!=6)
+    {
+      raw[0] = SWAP16((t->id<<6)|0x3f);
+      if (write(handle,raw,2)!=2)
+      {
+#ifdef DEBUG_RFXSWF
+          fprintf(stderr,"WriteTag() failed: Long Header (1).\n");
+#endif
+         return -1;
+      }
+      
+      len = SWAP32(len);
+      if (write(handle,&len,4)!=4)
       {
         #ifdef DEBUG_RFXSWF
-          fprintf(stderr,"WriteTag() failed: Long Header.\n");
+          fprintf(stderr,"WriteTag() failed: Long Header (2).\n");
         #endif
         return -1;
       }
@@ -649,9 +660,17 @@ int RFXSWF_WriteTag(int handle,TAG * t)
   return t->len+(short_tag?2:6);
 }
 
+int swf_WriteTag(int handle,TAG * t)
+{
+    return RFXSWF_WriteTag(handle, t);
+}
+
 int RFXSWF_DefineSprite_GetRealSize(TAG * t)
 // Sprite Handling: Helper function to pack DefineSprite-Tag
 { U32 len = t->len;
+  if(len>4) { // folded sprite
+      return t->len;
+  }
   do
   { t = swf_NextTag(t);
     if (t->id!=ST_DEFINESPRITE) len += RFXSWF_WriteTag(-1,t);
@@ -660,11 +679,105 @@ int RFXSWF_DefineSprite_GetRealSize(TAG * t)
   return len;
 }
 
+void swf_FoldSprite(TAG * t)
+{
+  TAG*sprtag=t,*tmp;
+  U16 id,frames,tmpid;
+  if(t->id!=ST_DEFINESPRITE)
+      return;
+  if(!t->len) {
+      fprintf(stderr, "Error: Sprite has no ID!");
+      return;
+  }
+
+  t->pos = 0;
+  id = swf_GetU16(t);
+  //frames = swf_GetU16(t);
+  free(t->data);
+  t->len = t->pos = t->memsize = 0;
+  t->data = 0;
+
+  frames = 0;
+
+  do 
+  { 
+    if(t->id==ST_SHOWFRAME) frames++;
+    t = swf_NextTag(t);
+  } while(t&&t!=ST_END);
+
+  t = swf_NextTag(sprtag);
+  swf_SetU16(sprtag, id);
+  swf_SetU16(sprtag, frames);
+
+  do
+  { 
+    tmpid= t->id;
+    if(t->len<0x3f) {
+       swf_SetU16(sprtag,t->len|(t->id<<6));
+    } else {
+       swf_SetU16(sprtag,0x3f|(t->id<<6));
+       swf_SetU32(sprtag,t->len);
+    }
+    if(t->len)
+       swf_SetBlock(sprtag,t->data, t->len);
+    tmp = t;
+    t = swf_NextTag(t);
+    swf_DeleteTag(tmp);
+  } 
+  while (t&&(tmpid!=ST_END));
+
+//  sprtag->next = t;
+//  t->prev = sprtag;
+}
+
+void swf_FoldAll(SWF*swf)
+{
+    TAG*tag = swf->firstTag;
+    while(tag) {
+       if(tag->id == ST_DEFINESPRITE)
+           swf_FoldSprite(tag);
+       tag = swf_NextTag(tag);
+    }
+}
+
 #define swf_ReadTag(a,b)  RFXSWF_ReadTag(a,b)
-#define swf_WriteTag(a,b) RFXSWF_WriteTag(a,b)
+#define swf_WriteTag(a,b)  RFXSWF_WriteTag(a,b)
 
 // Movie Functions
 
+int swf_InitSWF(void*data, int length, SWF * swf) /* copy a swf in memory into SWF struct */
+{
+  TAG reader;
+    /* 
+       unfinished!
+     */
+  *(int*)0=0xDEAD;
+  if (!swf) return -1;
+  memset(swf,0x00,sizeof(SWF));
+  memset(&reader,0x00,sizeof(TAG));
+  reader.data = data;
+  reader.len = reader.memsize = length;
+
+  { char b[32];                         // read Header
+    TAG * t;
+    
+    if (swf_GetU8(&reader)!=(U8)'F') return -1;
+    if (swf_GetU8(&reader)!=(U8)'W') return -1;
+    if (swf_GetU8(&reader)!=(U8)'S') return -1;
+
+    swf->fileVersion = swf_GetU8(&reader);
+    swf->fileSize    = swf_GetU32(&reader);
+    swf_GetRect(&reader,&swf->movieSize);
+    swf->frameRate   = swf_GetU16(&reader);
+    swf->frameCount  = swf_GetU16(&reader);
+
+    /*t = &t1;
+    while (t) t = swf_ReadTag(handle,t);
+    swf->firstTag = t1.next;
+    t1.next->prev = NULL;*/
+  }
+}
+
 int swf_ReadSWF(int handle,SWF * swf)   // Reads SWF to memory (malloc'ed), returns length or <0 if fails
 {     
   if (!swf) return -1;
@@ -701,6 +814,7 @@ int swf_ReadSWF(int handle,SWF * swf)   // Reads SWF to memory (malloc'ed), retu
   
   return 0;
 }
+
 int  swf_WriteSWF(int handle,SWF * swf)     // Writes SWF to file, returns length or <0 if fails
 { U32 len;
   TAG * t;
@@ -711,7 +825,7 @@ int  swf_WriteSWF(int handle,SWF * swf)     // Writes SWF to file, returns lengt
 
 #ifdef INSERT_RFX_TAG
 
-  if (swf_NextTag(swf->firstTag))
+  if (swf->firstTag && swf_NextTag(swf->firstTag))
     if (swf_GetTagID(swf_NextTag(swf->firstTag))!=ST_REFLEX)
       swf_SetBlock(swf_InsertTag(swf->firstTag,ST_REFLEX),"rfx",3);
 
@@ -742,15 +856,17 @@ int  swf_WriteSWF(int handle,SWF * swf)     // Writes SWF to file, returns lengt
     swf_SetU8(&t1,'S');
     swf_SetU8(&t1,swf->fileVersion);
     
-    swf_SetU32(&t1,0);                      // Keep space for filesize
+    swf_SetU32(&t1,swf->fileSize);         // Keep space for filesize
     swf_SetRect(&t1,&swf->movieSize);
     swf_SetU16(&t1,swf->frameRate);
     swf_SetU16(&t1,swf->frameCount);
 
     l = swf_GetTagLen(&t1);
     swf->fileSize = l+len;
-    t1.len = 4;                         // bad & ugly trick !
-    swf_SetU32(&t1,swf->fileSize);
+    if(swf->firstTag) {
+       t1.len = 4;                         // bad & ugly trick !
+       swf_SetU32(&t1,swf->fileSize);
+    }
 
     if (handle>=0)
     { 
@@ -775,6 +891,14 @@ int  swf_WriteSWF(int handle,SWF * swf)     // Writes SWF to file, returns lengt
   return (int)swf->fileSize;
 }
 
+int swf_WriteHeader(int handle,SWF * swf)
+{
+    SWF myswf;
+    memcpy(&myswf,swf,sizeof(SWF));
+    myswf.firstTag = 0;
+    swf_WriteSWF(handle, &myswf);
+}
+
 int swf_WriteCGI(SWF * swf)
 { int len;
   char s[1024];
@@ -817,6 +941,7 @@ void swf_FreeTags(SWF * swf)                 // Frees all malloc'ed memory for t
 #include "modules\swfcgi.c"
 #include "modules\swfbits.c"
 #include "modules\swfaction.c"
+#include "modules\swfsound.c"
 
 #else
 
@@ -829,6 +954,7 @@ void swf_FreeTags(SWF * swf)                 // Frees all malloc'ed memory for t
 #include "modules/swfcgi.c"
 #include "modules/swfbits.c"
 #include "modules/swfaction.c"
+#include "modules/swfsound.c"
 
 #endif