added protection against using both --cat and --stack
[swftools.git] / src / swfcombine.c
index e595d26..8981b1d 100644 (file)
@@ -137,7 +137,7 @@ int args_callback_option(char*name,char*val) {
     {
 
        float rate = atof(val);
-       if ((rate < 1.0/256) ||(rate >= 256.0)) {
+       if ((rate < 0) ||(rate >= 256.0)) {
            fprintf(stderr, "Error: You must specify a valid framerate between 1/256 and 255.\n");
            exit(1);
        }
@@ -288,7 +288,7 @@ static void makestackmaster(SWF*swf)
     TAG*tag;
     int t;
     SRECT box;
-    int fileversion = 1;
+    int fileversion = config.zlib?6:3;
     int frameRate = 256;
     RGBA rgb;
     rgb.r=rgb.b=rgb.g=0;
@@ -306,6 +306,7 @@ static void makestackmaster(SWF*swf)
            exit(1);
        }
        close(fi);
+       swf_RemoveJPEGTables(&head);
        msg("<verbose> File %s has bounding box %d:%d:%d:%d\n",
                slave_filename[t], 
                head.movieSize.xmin, head.movieSize.ymin,
@@ -480,13 +481,19 @@ TAG* write_sprite_defines(TAG*tag, SWF*sprite)
                    case ST_SETBACKGROUNDCOLOR:
                       msg("<debug> deliberately ignoring BACKGROUNDCOLOR tag");
                       break;
+                   case ST_SHOWFRAME:
+                      msg("<debug> deliberately ignoring SHOWFRAME tag");
+                      break;
+                   case ST_REFLEX:
+                      msg("<debug> deliberately ignoring REFLEX tag");
+                      break;
                    case 40:
                    case 49:
                    case 51:
-                      msg("<notice> found tag %d. This is a Generator template, isn't it?", tag->id);
+                      msg("<notice> found tag %d. This is a Generator template, isn't it?", rtag->id);
                       break;
                    default:
-                      msg("<notice> funny tag: %d is neither defining nor sprite", tag->id);
+                      msg("<notice> funny tag: %d is neither defining nor sprite", rtag->id);
                }
            }
        }
@@ -497,7 +504,6 @@ TAG* write_sprite_defines(TAG*tag, SWF*sprite)
 
 void changedepth(TAG*tag, int add)
 {
-    /* fucking byteorders */
     if(tag->id == ST_PLACEOBJECT)
        PUT16(&tag->data[2],GET16(&tag->data[2])+add);
     if(tag->id == ST_PLACEOBJECT2)
@@ -506,6 +512,23 @@ void changedepth(TAG*tag, int add)
        PUT16(&tag->data[2],GET16(&tag->data[2])+add);
     if(tag->id == ST_REMOVEOBJECT2)
        PUT16(&tag->data[0],GET16(&tag->data[0])+add);
+    if(tag->id == ST_PLACEOBJECT2) {
+       SWFPLACEOBJECT obj;
+       U8 flags;
+       swf_SetTagPos(tag, 0);
+       flags = swf_GetU8(tag);
+       if(flags&2) swf_GetU16(tag); //id
+       if(flags&4) swf_GetMatrix(tag, 0);
+       if(flags&8) swf_GetCXForm(tag, 0,1);
+       if(flags&16) swf_GetU16(tag); //ratio
+       if(flags&64) {
+           swf_ResetReadBits(tag);
+           printf("%d->%d\n", GET16(&tag->data[tag->pos]),
+                              GET16(&tag->data[tag->pos])+add);
+           PUT16(&tag->data[tag->pos],GET16(&tag->data[tag->pos])+add);
+       }
+       msg("<warning> Depth relocation not fully working yet with clipdepths", tag->id);
+    }
 }
 
 void matrix_adjust(MATRIX*m, int movex, int movey, float scalex, float scaley, int scalepos)
@@ -524,7 +547,7 @@ void matrix_adjust(MATRIX*m, int movex, int movey, float scalex, float scaley, i
 
 void write_changepos(TAG*output, TAG*tag, int movex, int movey, float scalex, float scaley, int scalepos)
 {
-    if(movex || movey || scalex != 1 || scaley != 1)
+    if(movex || movey || scalex != 1.0 || scaley != 1.0)
     {
        switch(tag->id)
        {
@@ -551,7 +574,8 @@ void write_changepos(TAG*output, TAG*tag, int movex, int movey, float scalex, fl
                matrix_adjust(&m, movex, movey, scalex, scaley, scalepos);
                swf_SetMatrix(output, &m);
 
-               //swf_ResetReadBits(tag);
+               if (tag->readBit)  { tag->pos++; tag->readBit = 0; } //swf_ResetReadBits(tag);
+
                swf_SetBlock(output, &tag->data[tag->pos], tag->len - tag->pos);
                break;
            }
@@ -564,7 +588,8 @@ void write_changepos(TAG*output, TAG*tag, int movex, int movey, float scalex, fl
                matrix_adjust(&m, movex, movey, scalex, scaley, scalepos);
                swf_SetMatrix(output, &m);
                
-               //swf_ResetReadBits(tag);
+               if (tag->readBit)  { tag->pos++; tag->readBit = 0; } //swf_ResetReadBits(tag);
+
                swf_SetBlock(output, &tag->data[tag->pos], tag->len - tag->pos);
                break;
            }
@@ -616,8 +641,9 @@ TAG* write_sprite(TAG*tag, SWF*sprite, int spriteid, int replaceddefine)
                    rtag->id, rtag->len);
            tag = swf_InsertTag(tag, rtag->id);
            write_changepos(tag, rtag, config.movex, config.movey, config.scalex, config.scaley, 0);
-       
-           changedepth(tag, +2);
+
+           if(config.clip || (config.overlay && !config.isframe))
+               changedepth(tag, +2);
 
            if(tag->id == ST_SHOWFRAME)
            {
@@ -641,9 +667,10 @@ static char tag_ok_for_slave(int id)
 TAG* write_master(TAG*tag, SWF*master, SWF*slave, int spriteid, int replaceddefine, int flags)
 {
     int outputslave = 0;
-    int frame = 0;
+    int frame = 1;
     int sframe = 0;
     int slavewritten = 0;
+    int deletedepth = -1;
 
     TAG* rtag = master->firstTag;
     TAG* stag = slave->firstTag;
@@ -668,6 +695,14 @@ TAG* write_master(TAG*tag, SWF*master, SWF*slave, int spriteid, int replaceddefi
        if(rtag->id == ST_SHOWFRAME)
        {
            frame ++;
+           tag = swf_InsertTag(tag, ST_SHOWFRAME);
+            if(deletedepth>=0) {
+                tag = swf_InsertTag(tag, ST_REMOVEOBJECT2);
+                swf_SetU16(tag, deletedepth);
+                deletedepth=-1;
+            }
+           rtag = rtag->next;
+            continue;
        }
 
        if(swf_isDefiningTag(rtag) && (flags&FLAGS_WRITEDEFINES))
@@ -701,7 +736,7 @@ TAG* write_master(TAG*tag, SWF*master, SWF*slave, int spriteid, int replaceddefi
                swf_SetBlock(tag, rtag->data, rtag->len);
            }
        }
-       if(frame == slaveframe)
+       if(frame == slaveframe) /* only happens with config.isframe: put slave at specific frame */
        {
            if(flags&FLAGS_WRITESLAVE) {
                outputslave = 1;
@@ -710,7 +745,8 @@ TAG* write_master(TAG*tag, SWF*master, SWF*slave, int spriteid, int replaceddefi
            if((flags&FLAGS_WRITESPRITE) && !slavewritten)
            {
                int id = get_free_id(masterbitmap);
-               int depth = 0;
+               int depth = 65535;
+               deletedepth = 65535;
                if(config.clip) {
                    msg("<fatal> Can't combine --clip and --frame");
                }
@@ -751,6 +787,7 @@ TAG* write_master(TAG*tag, SWF*master, SWF*slave, int spriteid, int replaceddefi
                        rtag->id, rtag->len);
                tag = swf_InsertTag(tag, rtag->id);
                write_changepos(tag, rtag, config.mastermovex, config.mastermovey, config.masterscalex, config.masterscaley, 1);
+               
            }
        }
        rtag = rtag->next;
@@ -955,7 +992,8 @@ void normalcombine(SWF*master, char*slave_name, SWF*slave, SWF*newswf)
     }
 
     swf_Relocate (slave, masterbitmap);
-    swf_RelocateDepth (slave, depthbitmap);
+    if(config.merge)
+       swf_RelocateDepth (slave, depthbitmap);
     jpeg_assert(slave, master);
     
     if (config.overlay)
@@ -1087,6 +1125,11 @@ int main(int argn, char *argv[])
        msg("<error> Can't combine --cat and --merge");
        exit(1);
     }
+    
+    if(config.stack && config.cat) {
+       msg("<error> Can't combine --cat and --stack");
+       exit(1);
+    }
 
     if(config.stack) {
        if(config.overlay) {
@@ -1114,6 +1157,7 @@ int main(int argn, char *argv[])
            msg("<fatal> Failed to read from %s\n", master_filename);
            exit(1);
        }
+       swf_RemoveJPEGTables(&master);
        msg("<debug> Read %d bytes from masterfile\n", ret);
        close(fi);
     }
@@ -1181,6 +1225,7 @@ int main(int argn, char *argv[])
                }
                msg("<debug> Read %d bytes from slavefile\n", ret);
                close(fi);
+               swf_RemoveJPEGTables(&slave);
            }
            else
            {
@@ -1194,13 +1239,21 @@ int main(int argn, char *argv[])
            combine(&master, slave_name[t], &slave, &newswf);
            master = newswf;
        }
+       if(config.dummy && !config.hassizex && !config.hassizey && !config.mastermovex && !config.mastermovey) {
+           newswf.movieSize.xmin = newswf.movieSize.xmin*config.masterscalex;
+           newswf.movieSize.ymin = newswf.movieSize.ymin*config.masterscaley;
+           newswf.movieSize.xmax = newswf.movieSize.xmax*config.masterscalex;
+           newswf.movieSize.ymax = newswf.movieSize.ymax*config.masterscaley;
+       }
     }
 
     fi = open(outputname, O_BINARY|O_RDWR|O_TRUNC|O_CREAT, 0777);
 
-    if(config.zlib)
+    if(config.zlib) {
+       if(newswf.fileVersion < 6)
+           newswf.fileVersion = 6;
        swf_WriteSWC(fi, &newswf);
-    else {
+    } else {
        newswf.compressed = 0;
        swf_WriteSWF(fi, &newswf);
     }