implemented sprite folding/unfolding.
[swftools.git] / lib / rfxswf.c
index 4a7035c..7824dee 100644 (file)
@@ -298,29 +298,6 @@ 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;
@@ -373,6 +350,10 @@ int swf_SetRect(TAG * t,SRECT * r)
   nbits = swf_CountBits(r->xmax,nbits);
   nbits = swf_CountBits(r->ymin,nbits);
   nbits = swf_CountBits(r->ymax,nbits);
+  if(nbits>=32) {
+    fprintf(stderr, "rfxswf: Warning: num_bits overflow in swf_SetRect\n");
+    nbits=31;
+  }
 
   swf_SetBits(t,nbits,5);
   swf_SetBits(t,r->xmin,nbits);
@@ -763,6 +744,51 @@ int swf_DefineSprite_GetRealSize(TAG * t)
   return len;
 }
 
+void swf_UnFoldSprite(TAG * t)
+{
+  U16 id,tmp;
+  U32 len;
+  TAG*next = t;
+  U16 spriteid,spriteframes;
+  if(t->id!=ST_DEFINESPRITE)
+    return;
+  if(t->len<=4) // not folded
+    return;
+
+  swf_SetTagPos(t,0);
+
+  spriteid = swf_GetU16(t); //id
+  spriteframes = swf_GetU16(t); //frames
+
+  tmp = swf_GetU16(t);
+  len = tmp&0x3f;
+  id  = tmp>>6;
+  while(id)
+  {
+    TAG*it = 0;
+    if (len==0x3f)
+       len = swf_GetU32(t);
+    it = swf_InsertTag(next, id);
+    next = it;
+    it->len = len;
+    it->id  = id;
+    if (it->len)
+    { it->data = (U8*)malloc(t->len);
+      it->memsize = it->len;
+      swf_GetBlock(t, it->data, it->len);
+    }
+    tmp = swf_GetU16(t);
+    len = tmp&0x3f;
+    id  = tmp>>6;
+  }
+  
+  free(t->data); t->data = 0;
+  t->memsize = t->len = t->pos = 0;
+
+  swf_SetU16(t, spriteid);
+  swf_SetU16(t, spriteframes);
+}
+
 void swf_FoldSprite(TAG * t)
 {
   TAG*sprtag=t,*tmp;
@@ -828,6 +854,17 @@ void swf_FoldAll(SWF*swf)
     }
 }
 
+void swf_UnFoldAll(SWF*swf)
+{
+    TAG*tag = swf->firstTag;
+    while(tag) {
+        TAG*next = swf_NextTag(tag);
+       if(tag->id == ST_DEFINESPRITE)
+           swf_UnFoldSprite(tag);
+       tag = next;
+    }
+}
+
 // Movie Functions
 
 int swf_ReadSWF2(struct reader_t*reader, SWF * swf)   // Reads SWF to memory (malloc'ed), returns length or <0 if fails
@@ -883,6 +920,7 @@ int  swf_WriteSWF2(struct writer_t*writer, SWF * swf)     // Writes SWF to file,
   TAG * t;
   int frameCount=0;
   struct writer_t zwriter;
+  int fileSize = 0;
     
   if (!swf) return -1;
 
@@ -928,8 +966,9 @@ int  swf_WriteSWF2(struct writer_t*writer, SWF * swf)     // Writes SWF to file,
       l = swf_GetTagLen(&t2)+8;
     }
 
+    fileSize = l+len;
     if(len) {// don't touch headers without tags
-       swf->fileSize = l+len;
+       swf->fileSize = fileSize;
        swf->frameCount = frameCount;
     }
    
@@ -976,7 +1015,7 @@ int  swf_WriteSWF2(struct writer_t*writer, SWF * swf)     // Writes SWF to file,
       writer->finish(writer); //e.g. flush zlib buffers
     }
   }
-  return (int)swf->fileSize;
+  return (int)fileSize;
 }
 
 int  swf_WriteSWF(int handle, SWF * swf)     // Writes SWF to file, returns length or <0 if fails