more solaris fixes
[swftools.git] / src / combine.c
index 4908912..4847a58 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,58 @@ 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;
+       PUT16(&tag->data[2],GET16(&tag->data[2])+add);
     if(tag->id == TAGID_PLACEOBJECT2)
-       (*(u16*)&tag->data[1]) += add;
+       PUT16(&tag->data[1],GET16(&tag->data[1])+add);
     if(tag->id == TAGID_REMOVEOBJECT)
-       (*(u16*)&tag->data[2]) += add;
+       PUT16(&tag->data[2],GET16(&tag->data[2])+add);
     if(tag->id == TAGID_REMOVEOBJECT2)
-       (*(u16*)&tag->data[0]) += add;
+       PUT16(&tag->data[0],GET16(&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 +205,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 +233,6 @@ void write_sprite_defines(struct writer_t*w)
     }
 }
 
-
 void write_sprite(struct writer_t*w, int spriteid, int replaceddefine)
 {
     u16 tmp;
@@ -200,7 +241,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);
@@ -208,9 +249,9 @@ void write_sprite(struct writer_t*w, int spriteid, int replaceddefine)
     startpos = (u8*)writer_getpos(w);
 
     logf ("<notice> sprite id is %d", spriteid);
-    tmp = spriteid;
+    tmp = SWAP16(spriteid);
     writer_write(w, &tmp, 2);
-    tmp = slave.header.count;
+    tmp = SWAP16(slave.header.count);
     writer_write(w, &tmp, 2);
 
 
@@ -219,26 +260,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 +301,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);
+    PUT32(tagidpos, (u8*)writer_getpos(w) - startpos); // set length of sprite (in header)
+    logf("<verbose> sprite length is %d",GET32(tagidpos));
 }
 
 static char tag_ok_for_slave(int id)
@@ -308,7 +349,7 @@ void write_master(struct writer_t*w, int spriteid, int replaceddefine, int flags
            {
                if(config.overlay)
                {
-                   *(u16*)master.tags[pos].data = replaceddefine;
+                   PUT16(master.tags[pos].data, replaceddefine);
                    writer_write(w, master.tags[pos].fulldata, master.tags[pos].fulllength);
                } else {
                    /* don't write this tag */
@@ -343,10 +384,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 ;
+               PUT16(&data[0], (u16)(TAGID_PLACEOBJECT2<<6) + 5);
                *(u8*)&data[2]= 2; //flags: id
-               *(u16*)&data[3]= depth; // depth
-               *(u16*)&data[5]= id;
+               PUT16(&data[3], depth);
+               PUT16(&data[5], id);
                write_sprite_defines(w);
                write_sprite(w, id, -1);
                writer_write(w,data,7);
@@ -455,6 +496,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 +550,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;
+           PUT16(&data[0], (TAGID_REMOVEOBJECT2<<6) + 2);
+           PUT16(&data[2], t);
            writer_write(&w, data, 4);
        }
        free(depths);
@@ -524,7 +566,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
+       PUT32(headlength, tmp32); // set the header to the correct length
 
        return newdata; //length
 }
@@ -601,8 +643,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 +674,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
+       PUT32(headlength, tmp32);
 
        return newdata; //length
 }
@@ -659,8 +701,8 @@ uchar * combine(uchar*masterdata, int masterlength, char*_slavename, uchar*slave
 
     logf("<debug> move x (%d)", config.movex);
     logf("<debug> move y (%d)", config.movey);
-    logf("<debug> scale x (%d)", config.scalex);
-    logf("<debug> scale y (%d)", config.scaley);
+    logf("<debug> scale x (%f)", config.scalex);
+    logf("<debug> scale y (%f)", config.scaley);
     logf("<debug> is frame (%d)", config.isframe);
     
     memset(masterids, -1, sizeof(masterids));