swf_SetDefineBBox().
[swftools.git] / lib / modules / swftools.c
index b192f33..c4f6e05 100644 (file)
@@ -136,6 +136,7 @@ SRECT swf_GetDefineBBox(TAG * t)
   U32 oldTagPos;
   U16 id = 0;
   SRECT b1,b2;
+  memset(&b1, 0, sizeof(b1));
 
   oldTagPos = swf_GetTagPos(t);
   swf_SetTagPos(t,0);
@@ -560,7 +561,7 @@ void enumerateUsedIDs(TAG * tag, int base, void (*callback)(TAG*, int, void*), v
                if(id == ST_END)
                    break;
                tag2->len = tag2->memsize = len;
-               tag2->data = malloc(len);
+               tag2->data = rfx_alloc(len);
                memcpy(tag2->data, &tag->data[tag->pos], len);
                /* I never saw recursive sprites, but they are (theoretically) 
                   possible, so better add base here again */
@@ -844,17 +845,19 @@ void swf_Relocate (SWF*swf, char*bitmap)
        } 
        
        num = swf_GetNumUsedIDs(tag);
-       ptr = malloc(sizeof(int)*num);
-       swf_GetUsedIDs(tag, ptr);
-
-       for(t=0;t<num;t++) {
-           int id = GET16(&tag->data[ptr[t]]);
-           if(slaveids[id]<0) {
-               fprintf(stderr, "swf_Relocate: Mapping id never encountered before: %d\n", id);
-               return ;
+       if(num) {
+           ptr = rfx_alloc(sizeof(int)*num);
+           swf_GetUsedIDs(tag, ptr);
+
+           for(t=0;t<num;t++) {
+               int id = GET16(&tag->data[ptr[t]]);
+               if(slaveids[id]<0) {
+                   fprintf(stderr, "swf_Relocate: Mapping id never encountered before: %d\n", id);
+                   return ;
+               }
+               id = slaveids[id];
+               PUT16(&tag->data[ptr[t]], id);
            }
-           id = slaveids[id];
-           PUT16(&tag->data[ptr[t]], id);
        }
        tag=tag->next;
     }
@@ -964,20 +967,17 @@ static int tagHash(TAG*tag)
         a >>= 8;
         a += tag->data[t]*0xefbc35a5*b*(t+1);
     }
-    return a&0x7fffffff; //always return unsigned
+    return a&0x7fffffff; //always return positive number
 }
 
 void swf_Optimize(SWF*swf)
 {
     const int hash_size = 131072;
-    char* dontremap = malloc(sizeof(char)*65536);
-    U16* remap = malloc(sizeof(U16)*65536);
-    TAG* id2tag = malloc(sizeof(TAG*)*65536);
-    TAG** hashmap = malloc(sizeof(TAG*)*hash_size);
+    char* dontremap = rfx_calloc(sizeof(char)*65536);
+    U16* remap = rfx_alloc(sizeof(U16)*65536);
+    TAG* id2tag = rfx_calloc(sizeof(TAG*)*65536);
+    TAG** hashmap = rfx_calloc(sizeof(TAG*)*hash_size);
     TAG* tag;
-    memset(dontremap, 0, sizeof(char)*65536);
-    memset(hashmap, 0, sizeof(TAG*)*hash_size);
-    memset(id2tag, 0, sizeof(TAG*)*65536);
     int t;
     for(t=0;t<65536;t++) {
         remap[t] = t;
@@ -992,8 +992,9 @@ void swf_Optimize(SWF*swf)
            FIXME: a better way would be to compare
                   the helper tags, too.
          */
-        if(swf_isPseudoDefiningTag(tag)) {
-            //dontremap[swf_GetDefineID(tag)] = 1; //FIXME
+        if(swf_isPseudoDefiningTag(tag) &&
+           tag->id != ST_NAMECHARACTER) {
+            dontremap[swf_GetDefineID(tag)] = 1;
         }
         tag=tag->next;
     }
@@ -1002,7 +1003,22 @@ void swf_Optimize(SWF*swf)
         int doremap=1;
         
         TAG*next = tag->next;
-        
+
+        /* remap the tag */
+        int num = swf_GetNumUsedIDs(tag);
+        int*positions = rfx_alloc(sizeof(int)*num);
+        int t;
+        swf_GetUsedIDs(tag, positions);
+        for(t=0;t<num;t++) {
+            int id = GET16(&tag->data[positions[t]]);
+            id = remap[id];
+            PUT16(&tag->data[positions[t]], id);
+        }
+        rfx_free(positions);
+        tag = tag->next;
+
+        /* now look for previous tags with the same
+           content */
         if(swf_isDefiningTag(tag)) {
             TAG*tag2;
             int id = swf_GetDefineID(tag);
@@ -1051,25 +1067,48 @@ void swf_Optimize(SWF*swf)
             }
         }
 
-        if(doremap)
-        {
-            int num = swf_GetNumUsedIDs(tag);
-            int*positions = malloc(sizeof(int)*num);
-            int t;
-            swf_GetUsedIDs(tag, positions);
-            for(t=0;t<num;t++) {
-                int id = GET16(&tag->data[positions[t]]);
-                id = remap[id];
-                PUT16(&tag->data[positions[t]], id);
-            }
-            free(positions);
-            tag = tag->next;
-        }
-
         tag = next;
     }
-    free(dontremap);
-    free(remap);
-    free(id2tag);
-    free(hashmap);
+    rfx_free(dontremap);
+    rfx_free(remap);
+    rfx_free(id2tag);
+    rfx_free(hashmap);
+}
+
+void swf_SetDefineBBox(TAG * tag, SRECT newbbox)
+{
+    U16 id = 0;
+    SRECT b1;
+    swf_SetTagPos(tag,0);
+
+    switch (swf_GetTagID(tag))
+    { 
+       case ST_DEFINESHAPE:
+       case ST_DEFINESHAPE2:
+       case ST_DEFINESHAPE3:
+       case ST_DEFINEEDITTEXT:
+       case ST_DEFINETEXT:
+       case ST_DEFINETEXT2:
+       case ST_DEFINEVIDEOSTREAM: {
+             U32 after_bbox_offset = 0, len;
+             U8*data;
+             id = swf_GetU16(tag);
+             swf_GetRect(tag, &b1);
+             swf_ResetReadBits(tag);
+             after_bbox_offset = tag->pos;
+             len = tag->len - after_bbox_offset;
+             data = malloc(len);
+             memcpy(data, &tag->data[after_bbox_offset], len);
+             tag->writeBit = 0;
+             tag->len = 2;
+             swf_SetRect(tag, &newbbox);
+             swf_SetBlock(tag, data, len);
+             free(data);
+             tag->pos = tag->readBit = 0;
+
+       } break;
+       default:
+           fprintf(stderr, "rfxswf: Tag %d (%s) has no bbox\n", tag->id, swf_TagGetName(tag));
+    }
 }
+