removed one wrong SWAP16
[swftools.git] / src / combine.c
index 4908912..1e391aa 100644 (file)
 #include <string.h>
 #include <memory.h>
 #include "../lib/log.h"
+#include "../lib/rfxswf.h"
 #include "./flash.h"
 #include "./reloc.h"
 #include "./settings.h"
 
-// TODO:
-// * readers should be object-oriented
-
 static char* slavename = 0;
 static int slaveid = -1;
 static int slaveframe = -1;
@@ -58,14 +56,62 @@ static int get_free_id()
 
 void changedepth(struct swf_tag*tag, int add)
 {
+    /* fucking big endian byte order */
     if(tag->id == TAGID_PLACEOBJECT)
-       (*(u16*)&tag->data[2]) += add;
+       (*(u16*)&tag->data[2]) =
+       SWAP16(SWAP16(*(u16*)&tag->data[2]) + add);
     if(tag->id == TAGID_PLACEOBJECT2)
-       (*(u16*)&tag->data[1]) += add;
+       (*(u16*)&tag->data[1]) =
+       SWAP16(SWAP16(*(u16*)&tag->data[1]) + add);
     if(tag->id == TAGID_REMOVEOBJECT)
-       (*(u16*)&tag->data[2]) += add;
+       (*(u16*)&tag->data[2]) =
+       SWAP16(SWAP16(*(u16*)&tag->data[2]) + add);
     if(tag->id == TAGID_REMOVEOBJECT2)
-       (*(u16*)&tag->data[0]) += add;
+       (*(u16*)&tag->data[0]) =
+       SWAP16(SWAP16(*(u16*)&tag->data[0]) + add);
+}
+
+void jpeg_assert()
+{
+    /* TODO: if there's a jpegtable found, store it
+       and handle it together with the flash file
+       headers */
+    /* check that master and slave don't have both
+       jpegtables (which would be fatal) */
+    int pos;
+    int mpos=-1, spos=-1;
+    pos = 0;
+    while(master.tags[pos].id != 0)
+    {
+       if(master.tags[pos].id == TAGID_JPEGTABLES)
+           mpos = pos;
+       pos++;
+    }
+    pos = 0;
+    while(master.tags[pos].id != 0)
+    {
+       if(slave.tags[pos].id == TAGID_JPEGTABLES)
+           spos = pos;
+       pos++;
+    }
+    if(spos>=0 && mpos>=0)
+    {
+       if(slave.tags[pos].length ==
+          master.tags[pos].length &&
+       !memcmp(slave.tags[pos].data, master.tags[pos].data,
+           master.tags[pos].length))
+       {
+           // ok, both have jpegtables, but they're identical.
+           // delete one and don't make an error
+           for(;spos<slave.tagnum-1;spos++)
+               slave.tags[spos] =
+                   slave.tags[spos+1];
+           spos = -1;
+       }
+    }
+    if(spos>=0 && mpos>=0) {
+       logf("<error> Master and slave have incompatible JPEGTABLES.");
+    }
 }
 
 /* applies the config move and scale parameters to
@@ -163,9 +209,9 @@ void write_sprite_defines(struct writer_t*w)
                        break;
                    }
                 case TAGID_JPEGTABLES:
-                       /* according to the flash specs, there may only 
-                          be one JPEGTABLES tag per swf. This is maybe
-                          a big FIXME */
+                       /* if we get here, jpeg_assert has already run,
+                          ensuring this is the only one of it's kind,
+                          so we may safely write it out */
                        writer_write(w, tag->fulldata, tag->fulllength);
                    break;
                 case TAGID_EXPORTASSETS:
@@ -191,7 +237,6 @@ void write_sprite_defines(struct writer_t*w)
     }
 }
 
-
 void write_sprite(struct writer_t*w, int spriteid, int replaceddefine)
 {
     u16 tmp;
@@ -200,7 +245,7 @@ void write_sprite(struct writer_t*w, int spriteid, int replaceddefine)
     u8*startpos;
     int pos = 0;
     // write slave(2) (header)
-    tmp = 0x3f + (TAGID_DEFINESPRITE << 6);
+    tmp = SWAP16(0x3f + (TAGID_DEFINESPRITE << 6));
     writer_write(w, &tmp, 2);
     tagidpos = (u32*)writer_getpos(w);
     writer_write(w, &tmp32, 4);
@@ -219,26 +264,26 @@ void write_sprite(struct writer_t*w, int spriteid, int replaceddefine)
     logf("<debug> %d frames to go",tmp);
 
     if(config.clip) {
-       tmp = 7 + (TAGID_PLACEOBJECT2 << 6);
+       tmp = SWAP16(7 + (TAGID_PLACEOBJECT2 << 6));
        writer_write(w, &tmp, 2);
-       tmp = 2+64; //flags: character + clipaction
+       tmp = SWAP16(2+64); //flags: character + clipaction
        writer_write(w, &tmp, 1);
-       tmp = 0; //depth
+       tmp = SWAP16(0); //depth
        writer_write(w, &tmp,2);
-       tmp = replaceddefine; //id
+       tmp = SWAP16(replaceddefine); //id
        writer_write(w, &tmp,2);
-       tmp = 65535; //clipdepth
+       tmp = SWAP16(65535); //clipdepth
        writer_write(w, &tmp,2);
     }
 
     if(config.overlay && !config.isframe) {
-       tmp = 5 + (TAGID_PLACEOBJECT2 << 6);
+       tmp = SWAP16(5 + (TAGID_PLACEOBJECT2 << 6));
        writer_write(w, &tmp, 2);
-       tmp = 2; //flags: character
+       tmp = SWAP16(2); //flags: character
        writer_write(w, &tmp, 1);
-       tmp = 0; //depth
+       tmp = SWAP16(0); //depth
        writer_write(w, &tmp,2);
-       tmp = replaceddefine; //id
+       tmp = SWAP16(replaceddefine); //id
        writer_write(w, &tmp,2);
     }
 
@@ -260,8 +305,8 @@ void write_sprite(struct writer_t*w, int spriteid, int replaceddefine)
     }
     while(slave.tags[pos++].id != TAGID_END);
 
-    *tagidpos = (u8*)writer_getpos(w) - startpos; // set length of sprite (in header)
-    logf("<verbose> sprite length is %d",*tagidpos);
+    *tagidpos = SWAP32((u8*)writer_getpos(w) - startpos); // set length of sprite (in header)
+    logf("<verbose> sprite length is %d",SWAP32(*tagidpos));
 }
 
 static char tag_ok_for_slave(int id)
@@ -308,7 +353,7 @@ void write_master(struct writer_t*w, int spriteid, int replaceddefine, int flags
            {
                if(config.overlay)
                {
-                   *(u16*)master.tags[pos].data = replaceddefine;
+                   *(u16*)master.tags[pos].data = SWAP16(replaceddefine);
                    writer_write(w, master.tags[pos].fulldata, master.tags[pos].fulllength);
                } else {
                    /* don't write this tag */
@@ -343,10 +388,10 @@ void write_master(struct writer_t*w, int spriteid, int replaceddefine, int flags
                if(config.clip) {
                    logf("<fatal> Can't combine --clip and --frame");
                }
-               *(u16*)&data[0] = (u16)(TAGID_PLACEOBJECT2<<6) + 5 ;
+               *(u16*)&data[0] = SWAP16((u16)(TAGID_PLACEOBJECT2<<6) + 5);
                *(u8*)&data[2]= 2; //flags: id
-               *(u16*)&data[3]= depth; // depth
-               *(u16*)&data[5]= id;
+               *(u16*)&data[3]= SWAP16(depth); // depth
+               *(u16*)&data[5]= SWAP16(id);
                write_sprite_defines(w);
                write_sprite(w, id, -1);
                writer_write(w,data,7);
@@ -455,6 +500,7 @@ uchar * catcombine(uchar*masterdata, int masterlength, char*_slavename, uchar*sl
        
        swf_relocate (slavedata, slavelength, masterids);
        read_swf(&slave, slavedata, slavelength);
+       jpeg_assert();
        
        writer_write(&w, "FWS",3);
        headlength = (u32*)(writer_getpos(&w) + 1);
@@ -508,8 +554,8 @@ uchar * catcombine(uchar*masterdata, int masterlength, char*_slavename, uchar*sl
        {
            char data[16];
            int len;
-           *(u16*)(&data[0]) = (TAGID_REMOVEOBJECT2<<6) + 2;
-           *(u16*)(&data[2]) = t;
+           *(u16*)(&data[0]) = SWAP16((TAGID_REMOVEOBJECT2<<6) + 2);
+           *(u16*)(&data[2]) = SWAP16(t);
            writer_write(&w, data, 4);
        }
        free(depths);
@@ -524,7 +570,7 @@ uchar * catcombine(uchar*masterdata, int masterlength, char*_slavename, uchar*sl
 
        tmp32 = (u8*)writer_getpos(&w) - (u8*)newdata; //length
        *newlength = tmp32;
-       *headlength = tmp32; // set the header to the correct length
+       *headlength = SWAP32(tmp32); // set the header to the correct length
 
        return newdata; //length
 }
@@ -601,8 +647,8 @@ uchar * normalcombine(uchar*masterdata, int masterlength, char*_slavename, uchar
        }
 
        swf_relocate (slavedata, slavelength, masterids);
-
        read_swf(&slave, slavedata, slavelength);
+       jpeg_assert();
        
        if (config.overlay)
            replaceddefine = get_free_id();
@@ -632,7 +678,7 @@ uchar * normalcombine(uchar*masterdata, int masterlength, char*_slavename, uchar
 
        tmp32 = (u8*)writer_getpos(&w) - (u8*)newdata; //length
        *newlength = tmp32;
-       *headlength = tmp32; // set the header to the correct length
+       *headlength = SWAP32(tmp32); // set the header to the correct length
 
        return newdata; //length
 }