new function swf_GetMorphGradient
[swftools.git] / lib / rfxswf.c
index 5347ba0..4a7035c 100644 (file)
 #endif // HAVE_ZLIB_H
 #endif // HAVE_LIBZ
 
+#define LAME
+#include "lame/lame.h"
+
+#include "./bitio.h"
+
 // internal constants
 
 #define MALLOC_SIZE     128
@@ -128,6 +133,7 @@ int swf_SetBlock(TAG * t,U8 * b,int l)
     {
       #ifdef DEBUG_RFXSWF
         fprintf(stderr,"Fatal Error: malloc()/realloc() failed (1). (%d bytes)\n", newmem);
+       *(int*)0=0;
       #endif
       return 0;
     }
@@ -198,9 +204,6 @@ U32 swf_GetBits(TAG * t,int nbits)
   return res;
 }
 
-/* reader/writer stuff - from ../src/bitio.c */
-#include "./bitio.c"
-
 S32 swf_GetSBits(TAG * t,int nbits)
 { U32 res = swf_GetBits(t,nbits);
   if (res&(1<<(nbits-1))) res|=(0xffffffff<<nbits);  
@@ -295,6 +298,29 @@ void swf_GetGradient(TAG * tag, GRADIENT * gradient, char alpha)
     }
 }
 
+void swf_GetMorphGradient(TAG * tag, GRADIENT * gradient1, GRADIENT * gradient2)
+{
+    GRADIENT dummy1;
+    GRADIENT dummy2;
+    int t;
+    if(!gradient1)
+       gradient1 = &dummy1;
+    if(!gradient2)
+       gradient2 = &dummy2;
+    gradient1->num = 
+    gradient2->num = swf_GetU8(tag);
+    for(t=0;t<gradient1->num;t++)
+    {
+       int s=t;
+       if(s>=8) //FIXME
+           s=7;
+       gradient1->ratios[t] = swf_GetU8(tag);
+       swf_GetRGBA(tag, &gradient1->rgba[t]);
+       gradient2->ratios[t] = swf_GetU8(tag);
+       swf_GetRGBA(tag, &gradient2->rgba[t]);
+    }
+}
+
 int swf_CountBits(U32 v,int nbits)
 { int n = 33;
   U32 m = 0x80000000;
@@ -747,6 +773,10 @@ void swf_FoldSprite(TAG * t)
       fprintf(stderr, "Error: Sprite has no ID!");
       return;
   }
+  if(t->len>4) {
+    /* sprite is already folded */
+      return;
+  }
 
   t->pos = 0;
   id = swf_GetU16(t);
@@ -838,7 +868,7 @@ int swf_ReadSWF2(struct reader_t*reader, SWF * swf)   // Reads SWF to memory (ma
     t1.next->prev = NULL;
   }
   
-  return 0;
+  return reader->pos;
 }
 
 int swf_ReadSWF(int handle, SWF * swf)
@@ -848,9 +878,10 @@ int swf_ReadSWF(int handle, SWF * swf)
   return swf_ReadSWF2(&reader, swf);
 }
 
-int  swf_WriteSWF2(struct writer_t*writer, SWF * swf, bool compress)     // Writes SWF to file, returns length or <0 if fails
+int  swf_WriteSWF2(struct writer_t*writer, SWF * swf)     // Writes SWF to file, returns length or <0 if fails
 { U32 len;
   TAG * t;
+  int frameCount=0;
   struct writer_t zwriter;
     
   if (!swf) return -1;
@@ -869,11 +900,11 @@ int  swf_WriteSWF2(struct writer_t*writer, SWF * swf, bool compress)     // Writ
 
   len = 0;
   t = swf->firstTag;
-  swf->frameCount = 0;
+  frameCount = 0;
 
   while(t)
   { len += swf_WriteTag(-1, t);
-    if (t->id==ST_SHOWFRAME) swf->frameCount++;
+    if (t->id==ST_SHOWFRAME) frameCount++;
     t = swf_NextTag(t);
   }
   
@@ -896,9 +927,13 @@ int  swf_WriteSWF2(struct writer_t*writer, SWF * swf, bool compress)     // Writ
       swf_SetU16(&t2, swf->frameCount);
       l = swf_GetTagLen(&t2)+8;
     }
-    swf->fileSize = l+len;
+
+    if(len) {// don't touch headers without tags
+       swf->fileSize = l+len;
+       swf->frameCount = frameCount;
+    }
    
-    if(compress) {
+    if(swf->compressed) {
       char*id = "CWS";
       writer->write(writer, id, 3);
     }
@@ -911,7 +946,7 @@ int  swf_WriteSWF2(struct writer_t*writer, SWF * swf, bool compress)     // Writ
     PUT32(b4, swf->fileSize);
     writer->write(writer, b4, 4);
 
-    if(compress) {
+    if(swf->compressed) {
       writer_init_zlibdeflate(&zwriter, writer);
       writer = &zwriter;
     }
@@ -947,29 +982,37 @@ int  swf_WriteSWF2(struct writer_t*writer, SWF * swf, bool compress)     // Writ
 int  swf_WriteSWF(int handle, SWF * swf)     // Writes SWF to file, returns length or <0 if fails
 {
   struct writer_t writer;
+  swf->compressed = 0;
   if(handle<0)
-    return swf_WriteSWF2(&writer, swf, FALSE);
+    return swf_WriteSWF2(&writer, swf);
   writer_init_filewriter(&writer, handle);
-  return swf_WriteSWF2(&writer, swf, FALSE);
+  return swf_WriteSWF2(&writer, swf);
 }
 
 int  swf_WriteSWC(int handle, SWF * swf)     // Writes SWF to file, returns length or <0 if fails
 {
   struct writer_t writer;
+  swf->compressed = 1;
   if(handle<0)
-    return swf_WriteSWF2(&writer, swf, TRUE);
+    return swf_WriteSWF2(&writer, swf);
   writer_init_filewriter(&writer, handle);
-  return swf_WriteSWF2(&writer, swf, TRUE);
+  return swf_WriteSWF2(&writer, swf);
 }
 
+int swf_WriteHeader2(struct writer_t*writer,SWF * swf)
+{
+  SWF myswf;
+  memcpy(&myswf,swf,sizeof(SWF));
+  myswf.firstTag = 0;
+  return swf_WriteSWF2(writer, &myswf);
+}
 
 int swf_WriteHeader(int handle,SWF * swf)
 {
   SWF myswf;
   memcpy(&myswf,swf,sizeof(SWF));
   myswf.firstTag = 0;
-  swf_WriteSWF(handle, &myswf);
-  return 0;
+  return swf_WriteSWF(handle, &myswf);
 }
 
 int swf_WriteCGI(SWF * swf)