From: kramm Date: Tue, 4 Jun 2002 15:55:03 +0000 (+0000) Subject: swfcombine now uses librfxswf. X-Git-Tag: release-0-4-0~65 X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=commitdiff_plain;h=c9b3f16f20729e72788ff3351dad975c96f6bba1 swfcombine now uses librfxswf. *Probably not working yet* --- diff --git a/src/Makefile.in b/src/Makefile.in index a0411e7..31b001a 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -72,21 +72,22 @@ WORDS_BIGENDIAN = @WORDS_BIGENDIAN@ bin_PROGRAMS = wav2swf png2swf swfcombine swfstrings swfextract swfdump @JPEG2SWF@ wav2swf_SOURCES = wav2swf.c wav.c wav.h png2swf_SOURCES = png2swf.c -swfextract_SOURCES = swfextract.c reloc.c bitio.c flash.c +swfextract_SOURCES = swfextract.c swfdump_SOURCES = swfdump.c -swfcombine_SOURCES = bitio.c bitio.h reloc.c reloc.h combine.c combine.h flash.c flash.h swfcombine.c types.h +swfcombine_SOURCES = swfcombine.c swfstrings_SOURCES = swfstrings.c jpeg2swf_SOURCES = jpeg2swf.c png2swf_LINK = $(CCLD) ../lib/librfxswf.a -o $@ wav2swf_LINK = $(CCLD) ../lib/librfxswf.a -o $@ swfextract_LINK = $(CCLD) -o $@ swfdump_LINK = $(CCLD) ../lib/librfxswf.a -o $@ -swfcombine_LINK = $(CCLD) ../lib/log.o -o $@ +swfcombine_LINK = $(CCLD) ../lib/librfxswf.a -o $@ swfstrings_LINK = $(CCLD) ../lib/librfxswf.a -o $@ jpeg2swf_LINK = $(CCLD) -o $@ wav2swf_LDADD = ../lib/librfxswf.a png2swf_LDADD = ../lib/librfxswf.a swfstrings_LDADD = ../lib/librfxswf.a +swfcombine_LDADD = ../lib/librfxswf.a swfdump_LDADD = ../lib/librfxswf.a swfextract_LDADD = ../lib/librfxswf.a jpeg2swf_LDADD = ../lib/librfxswf.a @@ -110,14 +111,13 @@ wav2swf_LDFLAGS = png2swf_OBJECTS = png2swf.o png2swf_DEPENDENCIES = ../lib/librfxswf.a png2swf_LDFLAGS = -swfcombine_OBJECTS = bitio.o reloc.o combine.o flash.o swfcombine.o -swfcombine_LDADD = $(LDADD) -swfcombine_DEPENDENCIES = +swfcombine_OBJECTS = swfcombine.o +swfcombine_DEPENDENCIES = ../lib/librfxswf.a swfcombine_LDFLAGS = swfstrings_OBJECTS = swfstrings.o swfstrings_DEPENDENCIES = ../lib/librfxswf.a swfstrings_LDFLAGS = -swfextract_OBJECTS = swfextract.o reloc.o bitio.o flash.o +swfextract_OBJECTS = swfextract.o swfextract_DEPENDENCIES = ../lib/librfxswf.a swfextract_LDFLAGS = swfdump_OBJECTS = swfdump.o diff --git a/src/bitio.c b/src/bitio.c deleted file mode 100644 index 029c4b9..0000000 --- a/src/bitio.c +++ /dev/null @@ -1,195 +0,0 @@ -/* bitio.c - Various routines for reading and writing bit- and bytewise, from and to memory. - - Part of the swftools package. - - Copyright (c) 2001 Matthias Kramm - - This file is distributed under the GPL, see file COPYING for details */ - -#include "bitio.h" - - -void reader_init(struct reader_t*r, uchar*newdata, int newlength) -{ - r->data = newdata; - r->datalength = newlength; - r->datapos = 0; - reader_resetbits(r); -} -void reader_skip(struct reader_t*r, int length) -{ - r->datapos += length; -} -void reader_resetbits(struct reader_t*r) -{ - r->bitpos = 8; -} - -void reader_input1(struct reader_t*r, void*target) -{ - *(uchar*)target = *(uchar*)&r->data[r->datapos]; - r->datapos ++; -} -void reader_input2(struct reader_t*r, void*target) -{ - *(u16*)target = GET16(&r->data[r->datapos]); - r->datapos += 2; -} -void reader_input4(struct reader_t*r, void*target) -{ - *(u32*)target = GET32(&r->data[r->datapos]); - r->datapos += 4; -} -uchar*reader_getinputpos(struct reader_t*r) -{ - return &r->data[r->datapos]; -} -int reader_getinputlength(struct reader_t*r) -{ - return r->datalength; -} -void reader_setinputpos(struct reader_t*r, uchar*pos) -{ - r->datapos = pos-r->data; -} -u32 reader_readbit(struct reader_t*r) -{ - if(r->bitpos==8) - { - r->bitpos=0; - reader_input1(r, &r->mybyte); - } - return (r->mybyte>>(7-r->bitpos++))&1; -} -void reader_readbits(struct reader_t*r, u32*val,int num) -{ - int t; - *val=0; - for(t=0;t>(num-1))&1) - { - x|=(0xffffffff<data = data; - w->maxlength = maxlength; - w->pos = 0; - w->bitpos = 0; - w->mybyte = 0; -} - -void writer_write(struct writer_t*w, void*data, int length) -{ - memcpy(&w->data[w->pos], data, length); - w->pos += length; -} - -void writer_writeu8(struct writer_t*w, u8 value) -{ - writer_resetbits(w); - writer_write(w, &value, 1); -} - -void writer_writeu16(struct writer_t*w, u16 value) -{ - u16 value2 = SWAP16(value); - writer_resetbits(w); - writer_write(w, &value2, 2); -} - -void writer_writeu32(struct writer_t*w, u32 value) -{ - u16 value2 = SWAP32(value); - writer_resetbits(w); - writer_write(w, &value2, 4); -} - -void* writer_getpos(struct writer_t*w) -{ - return &w->data[w->pos]; -} - -void writer_resetbits(struct writer_t*w) -{ - if(w->bitpos) - writer_write(w, &w->mybyte, 1); - w->bitpos = 0; - w->mybyte = 0; -} - -void writer_writebit(struct writer_t*w, int bit) -{ - if(w->bitpos==8) - { - writer_write(w, &w->mybyte, 1); - w->bitpos = 0; - w->mybyte = 0; - } - if(bit&1) - w->mybyte |= 1 << (7 - w->bitpos); - w->bitpos ++; -} - -void writer_writebits(struct writer_t*w, u32 data, int bits) -{ - int t; - for(t=0;t> (bits-t-1))&1); - } -} - diff --git a/src/bitio.h b/src/bitio.h deleted file mode 100644 index ee30eff..0000000 --- a/src/bitio.h +++ /dev/null @@ -1,60 +0,0 @@ -/* bitio.h - Header file for bitio.c. - - Part of the swftools package. - - Copyright (c) 2001 Matthias Kramm - - This file is distributed under the GPL, see file COPYING for details */ - -#ifndef __bitio_h__ -#define __bitio_h__ - -#include "types.h" -#include "../lib/rfxswf.h" - -struct reader_t { - u8* data; - int datalength; - int datapos; - u8 bitpos,mybyte; - u8 bitmem; -}; - -struct writer_t { - u8* data; - int maxlength; - int pos; - int bitpos; - u8 mybyte; -}; - -void reader_resetbits(struct reader_t*); -void reader_init(struct reader_t*,uchar*newdata, int newlength); -void reader_skip(struct reader_t*,int length); -void reader_input1(struct reader_t*, void*target); -void reader_input2(struct reader_t*, void*target); -void reader_input4(struct reader_t*, void*target); -uchar*reader_getinputpos(struct reader_t*); -int reader_getinputlength(struct reader_t*); -void reader_setinputpos(struct reader_t*,uchar*pos); -u32 reader_readbit(struct reader_t*); -void reader_readbits(struct reader_t*,u32*val,int num); -void reader_readsbits(struct reader_t*,s32*val,int num); -u32 reader_getbits(struct reader_t*,int num); -s32 reader_getsbits(struct reader_t*,int num); -u8 reader_readu8(struct reader_t*); -u16 reader_readu16(struct reader_t*); -u32 reader_readu32(struct reader_t*); - -void writer_init(struct writer_t*w, u8*data, int maxlength); -void writer_write(struct writer_t*w, void*data, int length); -void* writer_getpos(struct writer_t*w); -void writer_writebit(struct writer_t*w, int bit); -void writer_writebits(struct writer_t*w, u32 data, int bits); -void writer_writeu8(struct writer_t*w, u8 value); -void writer_writeu16(struct writer_t*w, u16 value); -void writer_writeu32(struct writer_t*w, u32 value); -void writer_resetbits(struct writer_t*w); - -#endif //__bitio_h__ diff --git a/src/combine.c b/src/combine.c deleted file mode 100644 index 9a033cb..0000000 --- a/src/combine.c +++ /dev/null @@ -1,750 +0,0 @@ -/* combine.c - Implements combine(), which merges two swfs in memory. - - Part of the swftools package. - - Copyright (c) 2001 Matthias Kramm - - This file is distributed under the GPL, see file COPYING for details */ - -#include -#include -#include -#include -#include "../lib/log.h" -#include "../lib/rfxswf.h" -#include "./flash.h" -#include "./reloc.h" -#include "./settings.h" - -static char* slavename = 0; -static int slaveid = -1; -static int slaveframe = -1; - -static char* tag_placeobject2_name (struct swf_tag* tag) -{ - struct PlaceObject2 plo2; - placeobject2_init (&plo2, tag); - return plo2.name; -} - -static u16 tag_placeobject2_character (struct swf_tag* tag) -{ - struct PlaceObject2 plo2; - placeobject2_init (&plo2, tag); - return plo2.id; -} - -static struct swffile master; -static struct swffile slave; - -static int masterids[65536]; - -static int get_free_id() -{ - int t; - for (t=1;t<65536;t++) - { - if(masterids[t] == -1) - { - masterids[t] = 1; - return t; - } - } - return -1; -} - -void changedepth(struct swf_tag*tag, int add) -{ - /* fucking big endian byte order */ - if(tag->id == TAGID_PLACEOBJECT) - PUT16(&tag->data[2],GET16(&tag->data[2])+add); - if(tag->id == TAGID_PLACEOBJECT2) - PUT16(&tag->data[1],GET16(&tag->data[1])+add); - if(tag->id == TAGID_REMOVEOBJECT) - PUT16(&tag->data[2],GET16(&tag->data[2])+add); - if(tag->id == TAGID_REMOVEOBJECT2) - 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(slave.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=0 && mpos>=0) { - logf(" Master and slave have incompatible JPEGTABLES."); - } -} - -/* applies the config move and scale parameters to - * a matrix. (If settings would provide a rotation, - * this would be a matrix concatenation/multiplication - * routine. In this case, it's just element-wise multiplication. - */ -void matrix_adjust(struct MATRIX*m) -{ - if(config.scalex != 1 || config.scaley != 1) - { - if(!m->hasscale) { - m->hasscale = 1; - m->a[0][0] = config.scalex; - m->a[1][1] = config.scaley; - } else { - m->a[0][0] *= config.scalex; - m->a[1][1] *= config.scaley; - } - if(m->hasrotate) { - m->a[0][1] *= config.scalex; - m->a[1][0] *= config.scaley; - } - m->b[0] *= config.scalex; - m->b[1] *= config.scaley; - } -/* printf("hasscale: %d\n",m->hasscale); - printf("hasrotate: %d\n", m->hasrotate); - printf("move: %d %d\n", m->b[0],m->b[1]); - printf("rot: %f %f\n",m->a[0][0],m->a[0][1]); - printf(" %f %f\n",m->a[1][0],m->a[1][1]);*/ - m->b[0] += config.movex; - m->b[1] += config.movey; -} - -void write_changepos(struct swf_tag*tag, struct writer_t*w) -{ - if(config.movex || config.movey || config.scalex != 1 || config.scaley != 1) - { - switch(tag->id) - { - case TAGID_PLACEOBJECT: { - struct PlaceObject p; - placeobject_init(&p, tag); - matrix_adjust(&p.matrix); - placeobject_write(&p, w); - break; - } - case TAGID_PLACEOBJECT2: { - struct PlaceObject2 p; - placeobject2_init(&p, tag); - if(!p.hasmatrix) { - p.hasmatrix = 1; - MATRIX_init(&p.matrix); - } - matrix_adjust(&p.matrix); - placeobject2_write(&p, w); - break; - } - default: - writer_write(w, tag->fulldata, tag->fulllength); - } - } - else - { - writer_write(w, tag->fulldata, tag->fulllength); - } -} - -void write_sprite_defines(struct writer_t*w) -{ - int pos = 0; - while(slave.tags[pos].id != 0) { - struct swf_tag * tag = &slave.tags[pos]; - if(!is_sprite_tag(tag->id)) { - logf(" processing sprite tag %02x", slave.tags[pos].id); - if(is_defining_tag(tag->id)) - { - logf(" [sprite defs] write tag %02x (%d bytes in body)", - tag->id, tag->length); - writer_write(w, tag->fulldata, tag->fulllength); - } - else - { - switch(tag->id) - {case TAGID_DEFINEFONTINFO: - { - /* define font info is not a defining tag, in that - * it doesn't define a new id, but rather extends - * an existing one. It also isn't a sprite tag. - * Anyway we can't throw it out, so we just pass it - * through. - */ - writer_write(w, tag->fulldata, tag->fulllength); - break; - } - case TAGID_JPEGTABLES: - /* 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: - logf(" deliberately ignoring EXPORTASSETS tag"); - break; - case TAGID_ENABLEDEBUGGER: - logf(" deliberately ignoring ENABLEDEBUGGER tag"); - break; - case TAGID_BACKGROUNDCOLOR: - logf(" deliberately ignoring BACKGROUNDCOLOR tag"); - break; - case 40: - case 49: - case 51: - logf(" found tag %d. This is a Generator template, isn't it?", slave.tags[pos].id); - break; - default: - logf(" funny tag: %d is neither defining nor sprite", slave.tags[pos].id); - } - } - } - pos++; - } -} - -void write_sprite(struct writer_t*w, int spriteid, int replaceddefine) -{ - u16 tmp; - u32 tmp32; - u32*tagidpos; - u8*startpos; - int pos = 0; - // write slave(2) (header) - tmp = SWAP16(0x3f + (TAGID_DEFINESPRITE << 6)); - writer_write(w, &tmp, 2); - tagidpos = (u32*)writer_getpos(w); - writer_write(w, &tmp32, 4); - - startpos = (u8*)writer_getpos(w); - - logf (" sprite id is %d", spriteid); - tmp = SWAP16(spriteid); - writer_write(w, &tmp, 2); - tmp = SWAP16(slave.header.count); - writer_write(w, &tmp, 2); - - - // write slave(2) (body) - tmp = slave.header.count; - logf(" %d frames to go",tmp); - - if(config.clip) { - tmp = SWAP16(7 + (TAGID_PLACEOBJECT2 << 6)); - writer_write(w, &tmp, 2); - tmp = SWAP16(2+64); //flags: character + clipaction - writer_write(w, &tmp, 1); - tmp = SWAP16(0); //depth - writer_write(w, &tmp,2); - tmp = SWAP16(replaceddefine); //id - writer_write(w, &tmp,2); - tmp = SWAP16(65535); //clipdepth - writer_write(w, &tmp,2); - } - - if(config.overlay && !config.isframe) { - tmp = SWAP16(5 + (TAGID_PLACEOBJECT2 << 6)); - writer_write(w, &tmp, 2); - tmp = SWAP16(2); //flags: character - writer_write(w, &tmp, 1); - tmp = SWAP16(0); //depth - writer_write(w, &tmp,2); - tmp = SWAP16(replaceddefine); //id - writer_write(w, &tmp,2); - } - - do { - struct swf_tag * tag = &slave.tags[pos]; - if (is_sprite_tag(tag->id)) { - - changedepth(tag, +1); - logf(" [sprite main] write tag %02x (%d bytes in body)", - slave.tags[pos].id, slave.tags[pos].length); - write_changepos(tag, w); - - if(tag->id == TAGID_SHOWFRAME) - { - tmp--; - logf(" %d frames to go",tmp); - } - } - } - while(slave.tags[pos++].id != TAGID_END); - - PUT32(tagidpos, (u8*)writer_getpos(w) - startpos); // set length of sprite (in header) - logf(" sprite length is %d",GET32(tagidpos)); -} - -static char tag_ok_for_slave(int id) -{ - if(id == TAGID_BACKGROUNDCOLOR) - return 0; - return 1; -} - -#define FLAGS_WRITEDEFINES 1 -#define FLAGS_WRITENONDEFINES 2 -#define FLAGS_WRITESPRITE 4 -#define FLAGS_WRITESLAVE 8 -void write_master(struct writer_t*w, int spriteid, int replaceddefine, int flags) -{ - int pos = 0; - int spos = 0; - int outputslave = 0; - int frame = 0; - int sframe = 0; - int slavewritten = 0; - while(master.tags[pos].id != 0) - { - if(master.tags[pos].id == TAGID_SHOWFRAME && outputslave) - { - while(slave.tags[spos].id) { - if(slave.tags[spos].id == TAGID_SHOWFRAME) { - spos++; - sframe++; - break; - } - if(tag_ok_for_slave(slave.tags[spos].id)) - writer_write(w, slave.tags[spos].fulldata, slave.tags[spos].fulllength); - spos++; - } - frame ++; - } - - if(is_defining_tag(master.tags[pos].id) && (flags&FLAGS_WRITEDEFINES)) - { - logf(" [master] write tag %02x (%d bytes in body)", - master.tags[pos].id, master.tags[pos].length); - if(getidfromtag(&master.tags[pos]) == spriteid && !config.isframe) - { - if(config.overlay) - { - PUT16(master.tags[pos].data, replaceddefine); - writer_write(w, master.tags[pos].fulldata, master.tags[pos].fulllength); - } else { - /* don't write this tag */ - logf(" replacing tag %d id %d with sprite", master.tags[pos].id - ,spriteid); - } - - if(flags&FLAGS_WRITESPRITE) - { - write_sprite_defines(w); - write_sprite(w, spriteid, replaceddefine); - } - if(flags&FLAGS_WRITESLAVE) - { - outputslave = 1; - } - } else { - writer_write(w, master.tags[pos].fulldata, master.tags[pos].fulllength); - } - } - if(frame == slaveframe) - { - if(flags&FLAGS_WRITESLAVE) { - outputslave = 1; - slavewritten = 1; - } - if((flags&FLAGS_WRITESPRITE) && !slavewritten) - { - int id = get_free_id(); - int depth = 0; - char data[7]; - if(config.clip) { - logf(" Can't combine --clip and --frame"); - } - PUT16(&data[0], (u16)(TAGID_PLACEOBJECT2<<6) + 5); - *(u8*)&data[2]= 2; //flags: id - PUT16(&data[3], depth); - PUT16(&data[5], id); - write_sprite_defines(w); - write_sprite(w, id, -1); - writer_write(w,data,7); - slavewritten = 1; - } - } - if(!is_defining_tag(master.tags[pos].id) && (flags&FLAGS_WRITENONDEFINES)) - { - int dontwrite = 0; - switch(master.tags[pos].id) { - case TAGID_PLACEOBJECT: - case TAGID_PLACEOBJECT2: - if(frame == slaveframe && !config.overlay) - dontwrite = 1; - case TAGID_REMOVEOBJECT: -// case TAGID_REMOVEOBJECT2: - /* place/removetags for the object we replaced - should be discarded, too, as the object to insert - isn't a sprite - */ - if(spriteid>=0 && getidfromtag(&master.tags[pos]) == spriteid && - !config.isframe && config.merge) - dontwrite = 1; - break; - } - if(!dontwrite) { - logf(" [master] write tag %02x (%d bytes in body)", - master.tags[pos].id, master.tags[pos].length); - writer_write(w, master.tags[pos].fulldata, master.tags[pos].fulllength); - } - } - pos++; - } - - if(outputslave) - while(slave.tags[spos].id) - { - if(tag_ok_for_slave(slave.tags[spos].id)) - writer_write(w, slave.tags[spos].fulldata, slave.tags[spos].fulllength); - spos++; - } - if(!slavewritten && config.isframe && (flags&(FLAGS_WRITESLAVE|FLAGS_WRITESPRITE))) - { - logf(" Frame %d doesn't exist in file. No substitution will occur", - slaveframe); - } - //write END tag: - writer_write(w, master.tags[pos].fulldata, master.tags[pos].fulllength); -} - -void writeheader(struct writer_t*w, u8*data, int length) -{ - if(config.hassizex || config.hassizey || config.framerate) - { - struct flash_header head; - struct reader_t reader; - swf_init(&reader, data-3, length+3); - head = swf_read_header(&reader); - if(config.hassizex) - { - head.boundingBox.x2 = head.boundingBox.x1 + config.sizex; - } - if(config.hassizey) - { - head.boundingBox.y2 = head.boundingBox.y1 + config.sizey; - } - if(config.framerate) - { - head.rate = config.framerate; - } - swf_write_header(w, &head); - } - else - writer_write(w, data, length); -} - -uchar * catcombine(uchar*masterdata, int masterlength, char*_slavename, uchar*slavedata, int slavelength, int*newlength) -{ - struct writer_t w; - u32*headlength; - u32 tmp32; - int length = masterlength*2 + slavelength; - int pos = 0; - int t; - char* depths; - uchar*newdata = malloc(length); - if(!newdata) { - logf(" Couldn't allocate %d bytes of memory", length); - return 0; - } - if(config.isframe) { - logf(" Can't combine --cat and --frame"); - exit(1); - } - writer_init(&w, newdata, length); - - do { - int tag = master.tags[pos].id; - if(is_defining_tag(tag)) { - int defineid = getidfromtag(&master.tags[pos]); - logf(" tagid %02x defines object %d", tag, defineid); - masterids[defineid] = 1; - } - } - while(master.tags[pos++].id != 0); - - swf_relocate (slavedata, slavelength, masterids); - read_swf(&slave, slavedata, slavelength); - jpeg_assert(); - - writer_write(&w, "FWS",3); - headlength = (u32*)(writer_getpos(&w) + 1); - writeheader(&w, master.header.headerdata, master.header.headerlength); - - depths = malloc(65536); - if(!depths) { - logf(" Couldn't allocate %d bytes of memory", 65536); - return 0; - } - memset(depths, 0, 65536); - pos = 0; - do { - int num=1; - u16 depth; - logf(" [master] write tag %02x (%d bytes in body)", - master.tags[pos].id, master.tags[pos].length); - switch(master.tags[pos].id) { - case TAGID_PLACEOBJECT2: - num++; - case TAGID_PLACEOBJECT: { - struct reader_t r; - reader_init (&r, master.tags[pos].data, master.tags[pos].length); - if(num>=2) - reader_readu8(&r); - depth = reader_readu16(&r); - depths[depth] = 1; - } - break; - case TAGID_REMOVEOBJECT: { - struct reader_t r; - reader_init (&r, master.tags[pos].data, master.tags[pos].length); - reader_readu16(&r); - depths[reader_readu16(&r)] = 0; - } - break; - case TAGID_REMOVEOBJECT2: { - struct reader_t r; - reader_init (&r, master.tags[pos].data, master.tags[pos].length); - depths[reader_readu16(&r)] = 0; - } - break; - } - if(master.tags[pos].id != 0) - writer_write(&w, master.tags[pos].fulldata, master.tags[pos].fulllength); - } - while(master.tags[pos++].id != 0); - - for(t=0;t<65536;t++) - if(depths[t]) - { - char data[16]; - int len; - PUT16(&data[0], (TAGID_REMOVEOBJECT2<<6) + 2); - PUT16(&data[2], t); - writer_write(&w, data, 4); - } - free(depths); - - pos = 0; - do { - logf(" [slave] write tag %02x (%d bytes in body)", - slave.tags[pos].id, slave.tags[pos].length); - writer_write(&w, slave.tags[pos].fulldata, slave.tags[pos].fulllength); - } - while(slave.tags[pos++].id != 0); - - tmp32 = (u8*)writer_getpos(&w) - (u8*)newdata; //length - *newlength = tmp32; - PUT32(headlength, tmp32); // set the header to the correct length - - return newdata; //length -} - -uchar * normalcombine(uchar*masterdata, int masterlength, char*_slavename, uchar*slavedata, int slavelength, int*newlength) -{ - int length; - int pos=0; - u32 tmp32; - u32*headlength; - uchar*newdata; - int spriteid = -1; - int replaceddefine = -1; - struct writer_t w; - int frame = 0; - char*framelabel; - - length = masterlength + slavelength*2 + 128; // this is a guess, but a good guess. - newdata = malloc(length); - writer_init(&w, newdata, length); - - if(!newdata) { - logf(" Couldn't allocate %d bytes of memory", length); - return 0; - } - - // set the idtab - pos = 0; - do { - int tag = master.tags[pos].id; - if(is_defining_tag(tag)) { - int defineid = getidfromtag(&master.tags[pos]); - logf(" tagid %02x defines object %d", tag, defineid); - masterids[defineid] = 1; - } else if(tag == TAGID_PLACEOBJECT2) { - char * name = tag_placeobject2_name(&master.tags[pos]); - int id = tag_placeobject2_character(&master.tags[pos]); - - if(name) - logf(" tagid %02x places object %d named \"%s\"", tag, id, name); - else - logf(" tagid %02x places object %d (no name)", tag, id); - - if ((name && slavename && !strcmp(name,slavename)) || - (!slavename && id==slaveid)) { - if(id>=0) { - spriteid = id; - logf(" Slave file attached to object %d.", id); - } - } - } else if(tag == TAGID_SHOWFRAME) { - if(slaveframe>=0 && frame==slaveframe) { - logf(" Slave file attached to frame %d.", frame); - } - frame++; - } else if(tag == TAGID_FRAMELABEL) { - char * name = master.tags[pos].data; - if(name && slavename && config.isframe && !strcmp(name, slavename)) { - slaveframe = frame; - logf(" Slave file attached to frame %d (%s).", frame, name); - } - } - } - while(master.tags[pos++].id != 0); - - if (spriteid<0 && !config.isframe) { - if(slavename) { - if(strcmp(slavename,"!!dummy!!")) - logf(" Didn't find anything named %s in file. No substitutions will occur.", slavename); - } - else - logf(" Didn't find id %d in file. No substitutions will occur.", slaveid); - spriteid = get_free_id(); - } - - swf_relocate (slavedata, slavelength, masterids); - read_swf(&slave, slavedata, slavelength); - jpeg_assert(); - - if (config.overlay) - replaceddefine = get_free_id(); - - // write file - - writer_write(&w, "FWS",3); - headlength = (u32*)(writer_getpos(&w) + 1); - writeheader(&w, master.header.headerdata, master.header.headerlength); - - if (config.antistream) { - if (config.merge) { - logf(" Can't combine --antistream and --merge"); - } - write_sprite_defines(&w); - write_sprite(&w, spriteid, replaceddefine); - write_master(&w, spriteid, replaceddefine, FLAGS_WRITEDEFINES); - write_master(&w, spriteid, replaceddefine, FLAGS_WRITENONDEFINES); - } else { - if (config.merge) - write_master(&w, spriteid, replaceddefine, - FLAGS_WRITEDEFINES|FLAGS_WRITENONDEFINES|FLAGS_WRITESLAVE); - else - write_master(&w, spriteid, replaceddefine, - FLAGS_WRITEDEFINES|FLAGS_WRITENONDEFINES|FLAGS_WRITESPRITE); - } - - tmp32 = (u8*)writer_getpos(&w) - (u8*)newdata; //length - *newlength = tmp32; - PUT32(headlength, tmp32); - - return newdata; //length -} - -uchar * combine(uchar*masterdata, int masterlength, char*_slavename, uchar*slavedata, int slavelength, int*newlength) -{ - char master_flash = 0; - char slave_flash = 0; - slavename = _slavename; - - slaveid = -1; - slaveframe = -1; - - if(slavename[0] == '#') - { - slaveid = atoi(&slavename[1]); - slavename = 0; - } - if(config.isframe) - { - slaveframe = slaveid; - slaveid = -1; - } - - logf(" move x (%d)", config.movex); - logf(" move y (%d)", config.movey); - logf(" scale x (%f)", config.scalex); - logf(" scale y (%f)", config.scaley); - logf(" is frame (%d)", config.isframe); - - memset(masterids, -1, sizeof(masterids)); - - if(masterlength < 3) - { - logf(" the master file is too small (%d bytes)", masterlength); - return 0; - } - if(slavelength < 3) - { - logf(" the slave file is too small (%d bytes)", slavelength); - return 0; - } - if(masterdata[2] == 'S' && - masterdata[1] == 'W' && - masterdata[0] == 'F') - { - logf(" the master file is flash (swf) format\n"); - master_flash = 1; - } - else - logf(" the master file is not flash (swf) format!\n"); - - if(slavedata[2] == 'S' && - slavedata[1] == 'W' && - slavedata[0] == 'F') - { - logf(" the slave file is flash (swf) format\n"); - slave_flash = 1; - } - else - logf(" the slave file is not flash (swf) format!\n"); - - if(master_flash && slave_flash) { - read_swf(&master, masterdata, masterlength); - if(config.cat) - return catcombine(masterdata, masterlength, _slavename, slavedata, slavelength, newlength); - else - return normalcombine(masterdata, masterlength, _slavename, slavedata, slavelength, newlength); - } - - *newlength = 0; - return 0; -} diff --git a/src/combine.h b/src/combine.h deleted file mode 100644 index d522771..0000000 --- a/src/combine.h +++ /dev/null @@ -1,14 +0,0 @@ -/* combine.h - Header file for combine.c - - Part of the swftools package. - - Copyright (c) 2001 Matthias Kramm - - This file is distributed under the GPL, see file COPYING for details */ - -#ifndef __combine_h__ -#define __combine_h__ -unsigned char * combine(unsigned char*masterdata, int masterlength, - char*slavename, unsigned char*slavedata, int slavelength, int*newlength); -#endif //__combine_h__ diff --git a/src/flash.c b/src/flash.c deleted file mode 100644 index 7c73397..0000000 --- a/src/flash.c +++ /dev/null @@ -1,580 +0,0 @@ -/* flash.c - Various routines for reading and writing swf files and tags. - - Part of the swftools package. - - Copyright (c) 2001 Matthias Kramm - - This file is distributed under the GPL, see file COPYING for details */ - -#include "flash.h" -#include "bitio.h" - -void swf_init(struct reader_t*r, uchar*newdata, int newlength) -{ - reader_init (r, &newdata[3], newlength - 3); -} - -struct flash_header swf_read_header(struct reader_t*r) -{ - struct flash_header head; - u16 rate; - u16 count; - char version; - int length; - u8* oldpos = reader_getinputpos(r); - - reader_input1(r,&version); - head.version = version; - reader_input4(r,&length); - head.length = length; - - reader_resetbits(r); - head.boundingBox = readRECT(r); - reader_input2(r,&rate); - head.rate = rate; - reader_input2(r,&count); - head.count = count; - - head.headerlength = reader_getinputpos(r) - oldpos; - head.headerdata = oldpos; - - return head; -} - -void swf_write_header(struct writer_t*w, struct flash_header*head) -{ - writer_writeu8(w, head->version); - writer_writeu32(w, head->length); - - writer_writebits(w, 31, 5); - writer_writebits(w, head->boundingBox.x1, 31); - writer_writebits(w, head->boundingBox.x2, 31); - writer_writebits(w, head->boundingBox.y1, 31); - writer_writebits(w, head->boundingBox.y2, 31); - writer_resetbits(w); - writer_writeu16(w, head->rate); - writer_writeu16(w, head->count); -} - -struct RGB readRGB(struct reader_t*r) -{ - struct RGB rgb; - reader_input1(r,&rgb.r); - reader_input1(r,&rgb.g); - reader_input1(r,&rgb.b); - return rgb; -} - -struct RGBA readRGBA(struct reader_t*r) -{ - struct RGBA rgba; - reader_input1(r,&rgba.r); - reader_input1(r,&rgba.g); - reader_input1(r,&rgba.b); - reader_input1(r,&rgba.a); - return rgba; -} - -struct GRADIENT readGRADIENT(struct reader_t*r, int shape) -{ - struct GRADIENT gradient; - int t; - gradient.num = reader_readu8(r); - for(t=0;tx1, 31); - writer_writebits(&w, r->x2, 31); - writer_writebits(&w, r->y1, 31); - writer_writebits(&w, r->y2, 31); - writer_resetbits(&w); - *pos = writer_getpos(&w); -} - -struct CXFORM readCXFORM(struct reader_t*r, char alpha) -{ - struct CXFORM c; - int bits; - c.hasadd=reader_readbit(r); - c.hasmult=reader_readbit(r); - bits=reader_getbits(r,4); - c.alpha = alpha; - - if (c.hasmult) - { - c.rmult=reader_getsbits(r,bits)/65536.0; - c.gmult=reader_getsbits(r,bits)/65536.0; - c.bmult=reader_getsbits(r,bits)/65536.0; - if(c.alpha) - c.amult=reader_getsbits(r,bits)/65536.0; - } - if (c.hasadd) - { - c.radd=reader_getsbits(r,bits)/65536.0; - c.gadd=reader_getsbits(r,bits)/65536.0; - c.badd=reader_getsbits(r,bits)/65536.0; - if(c.alpha) - c.aadd=reader_getsbits(r,bits)/65536.0; - } - return c; -} - -void CXFORM_write(struct CXFORM *obj, struct writer_t*w) -{ - int bits = 15; - writer_writebit(w,obj->hasadd); - writer_writebit(w,obj->hasmult); - writer_writebits(w, bits, 4); - if (obj->hasmult) - { - writer_writebits(w, obj->rmult, bits); - writer_writebits(w, obj->gmult, bits); - writer_writebits(w, obj->bmult, bits); - if(obj->alpha) - writer_writebits(w, obj->amult, 4); - } - if (obj->hasadd) - { - writer_writebits(w, obj->radd, bits); - writer_writebits(w, obj->gadd, bits); - writer_writebits(w, obj->badd, bits); - if(obj->alpha) - writer_writebits(w, obj->aadd, 4); - } -} - -unsigned char* readSTRING(struct reader_t*r) -{ - unsigned char*now = reader_getinputpos(r); - char a; - do - { - reader_input1(r,&a); - } - while(a); - return now; -} -void MATRIX_init(struct MATRIX*m) -{ - m->hasrotate = 0; - m->hasscale = 0; - m->b[0] = 0; - m->b[1] = 0; - m->a[0][0] = 1; - m->a[1][1] = 1; - m->a[1][0] = 0; - m->a[0][1] = 0; -} -struct MATRIX readMATRIX(struct reader_t*r) -{ - struct MATRIX m; - u8 hasrotate; - u8 translatebits; - u32 translatex; - u32 translatey; - - m.a[0][0] = m.a[1][1] = 1; - m.a[0][1] = m.a[1][0] = 0; - m.hasscale=reader_readbit(r); - if(m.hasscale) - { - u8 scalebits=reader_getbits(r,5); - s32 scalex=reader_getsbits(r,scalebits); - s32 scaley=reader_getsbits(r,scalebits); - m.a[0][0]=scalex/65536.0; - m.a[1][1]=scaley/65536.0; - } - m.hasrotate=reader_readbit(r); - if(m.hasrotate) - { - u8 rotbits=reader_getbits(r,5); - s32 rotateskew0=reader_getsbits(r,rotbits); - s32 rotateskew1=reader_getsbits(r,rotbits); - m.a[0][1]=rotateskew0/65536.0; - m.a[1][0]=rotateskew1/65536.0; - } - - translatebits=reader_getbits(r,5); - translatex=reader_getsbits(r,translatebits); - translatey=reader_getsbits(r,translatebits); - m.b[0]=translatex; - m.b[1]=translatey; - - return m; -} - -void MATRIX_write(struct MATRIX * m , struct writer_t*w) -{ - writer_writebit (w, m->hasscale); - if(m->hasscale) - { - int bits = 31; - writer_writebits(w, bits, 5); - writer_writebits(w, (u32)(m->a[0][0]*65536.0), bits); - writer_writebits(w, (u32)(m->a[1][1]*65536.0), bits); - } - writer_writebit (w, m->hasrotate); - if(m->hasrotate) - { - int bits = 31; - writer_writebits(w, bits, 5); - writer_writebits(w, (u32)(m->a[0][1]*65536.0), bits); - writer_writebits(w, (u32)(m->a[1][0]*65536.0), bits); - } - - //translate - { - int bits = 31; - writer_writebits(w, bits, 5); - writer_writebits(w, (u32)(m->b[0]), bits); - writer_writebits(w, (u32)(m->b[1]), bits); - } -} - - -int swf_read_tag(struct reader_t*r, struct swf_tag* swftag) -{ - u8*pos2,*pos = reader_getinputpos(r); - u16 tag; - u32 taglength; - u32 tagid; - int t; - - reader_input2(r, &tag); - - taglength = tag & 0x3f; - if (taglength == 0x3f) - { - reader_input4(r, &taglength); - } - - swftag->id=tag>>6; - swftag->length = taglength; - swftag->data = reader_getinputpos(r); - reader_skip(r,taglength); - pos2 = reader_getinputpos(r); - swftag->fulllength = pos2 - pos; - swftag->fulldata = pos; - return 1; -} - -int swf_count_tags(struct reader_t*r) -{ - u8*pos = reader_getinputpos(r); - int t=0; - struct swf_tag tag; - - while(1) - { - swf_read_tag(r,&tag); - t++; - if (tag.id == 0) - break; - } - - reader_setinputpos(r,pos); - return t; -} - -void placeobject_init (struct PlaceObject*obj, struct swf_tag*tag) -{ - struct reader_t r; - reader_init (&r, tag->data, tag->length); - obj -> id = reader_readu16(&r); - obj -> depth = reader_readu16(&r); - obj -> matrix = readMATRIX(&r); - obj -> hascxform = (reader_getinputpos(&r) < &tag->data[tag->length]); - if(obj -> hascxform) - obj -> cxform = readCXFORM(&r, 0); -} - -void placeobject_write (struct PlaceObject*obj, struct writer_t*w) -{ - u16 taghead = 0x3f | TAGID_PLACEOBJECT<<6; - u8*pos; - u8*lenpos; - U32 len; - writer_resetbits(w); - writer_write(w, &taghead, 2); - lenpos = writer_getpos(w); - - writer_write(w, &taghead, 2); - writer_write(w, &taghead, 2); - - pos = writer_getpos(w); - - writer_write(w, &obj->id, 2); - writer_write(w, &obj->depth, 2); - MATRIX_write(&obj->matrix, w); - - if(obj->hascxform) - { - CXFORM_write(&obj->cxform, w); - } - writer_resetbits(w); - - len = (u8*)writer_getpos(w) - pos; - lenpos[0] = len; - lenpos[1] = len>>8; - lenpos[2] = len>>16; - lenpos[3] = len>>24; -} - -void placeobject2_init (struct PlaceObject2*obj,struct swf_tag*tag) -{ - struct reader_t r; - u8 b; - reader_init (&r, tag->data, tag->length); - b=reader_readu8(&r); - obj->reserved= (b>>7)&1; - obj->hasclipactions= (b>>6)&1; - obj->hasname= (b>>5)&1; - obj->hasratio= (b>>4)&1; - obj->hascolortransform=(b>>3)&1; - obj->hasmatrix= (b>>2)&1; - obj->hascharacter= (b>>1)&1; - obj->hasmove= (b>>0)&1; - - obj->depth = reader_readu16(&r); - obj->id = -1; - if(obj->hascharacter) { - obj->id = reader_readu16(&r); - } - if(obj->hasmatrix) { - obj->matrix = readMATRIX(&r); - } - if(obj->hascolortransform) { - obj->cxform = readCXFORM(&r,0); - } - if(obj->hasratio) { - obj->ratio=reader_readu16(&r); - } - obj->name = 0; - if(obj->hasname) { - obj->name=readSTRING(&r); - } - if(obj->hasclipactions) { - obj->clipactions=reader_readu16(&r); - } -} - -void placeobject2_write (struct PlaceObject2*obj, struct writer_t*w) -{ - u8 flags = obj->reserved<<7 | obj->hasclipactions<<6 | obj->hasname<<5 | obj->hasratio<<4 | - obj->hascolortransform<<3 | obj->hasmatrix<<2 | obj->hascharacter<<1 | obj->hasmove; - u16 taghead = SWAP16(0x3f | TAGID_PLACEOBJECT2<<6); - u8*pos; - u8*lenpos; - U32 len; - writer_resetbits(w); - writer_write(w, &taghead, 2); - lenpos = writer_getpos(w); - writer_write(w, &taghead, 2); - writer_write(w, &taghead, 2); - - pos = writer_getpos(w); - - writer_writeu8(w, flags); - writer_writeu16(w, obj->depth); - if(obj->hascharacter) - writer_writeu16(w, obj->id); - if(obj->hasmatrix) - MATRIX_write(&obj->matrix, w); - if(obj->hascolortransform) - CXFORM_write(&obj->cxform, w); - if(obj->hasratio) - writer_writeu16(w, obj->ratio); - writer_resetbits(w); - if(obj->hasname) - writer_write(w, obj->name, strlen(obj->name) + 1); - if(obj->hasclipactions) - writer_writeu16(w, obj->clipactions); - writer_resetbits(w); - - len = (u8*)writer_getpos(w) - pos; - lenpos[0] = len; - lenpos[1] = len>>8; - lenpos[2] = len>>16; - lenpos[3] = len>>24; -} - -void read_swf(struct swffile*swf, uchar*data, int length) -{ - int pos; - struct flash_header head; - int tagnum; - struct reader_t r; - swf_init(&r, data, length); - head = swf_read_header(&r); - logf(" [HEADER] the version is %d", head.version); - logf(" [HEADER] the length is %d", head.length); - logf(" [HEADER] the boundingBox is %d:%d:%d:%d", - head.boundingBox.x1,head.boundingBox.y1, - head.boundingBox.x2,head.boundingBox.y2); - logf(" [HEADER] the rate (frames/second) is %d", head.rate); - logf(" [HEADER] the count (frame number) is %d", head.count); - - tagnum = swf_count_tags(&r); - swf->tags = (struct swf_tag*)malloc(sizeof(struct swf_tag)*tagnum); - - logf(" [HEADER] the file consists of %d tags", tagnum); - - pos = 0; - while(1) - { - struct swf_tag tag; - swf_read_tag(&r, &tag); - logf(" read tag %02x (%d bytes)", tag.id, tag.length); - swf->tags[pos] = tag; - pos++; - if(tag.id == TAGID_END) - break; - } - swf->tagnum = tagnum; - swf->header = head; -} - -int definingtagids[] = -{TAGID_DEFINESHAPE, - TAGID_DEFINESHAPE2, - TAGID_DEFINESHAPE3, - TAGID_DEFINEMORPHSHAPE, - TAGID_DEFINEFONT, - TAGID_DEFINEFONT2, - TAGID_DEFINETEXT, - TAGID_DEFINETEXT2, - TAGID_DEFINEEDITTEXT, - TAGID_DEFINEBITS, - TAGID_DEFINEBITSJPEG2, - TAGID_DEFINEBITSJPEG3, - TAGID_DEFINEBITSLOSSLESS, - TAGID_DEFINEBITSLOSSLESS2, - TAGID_DEFINEMOVIE, - TAGID_DEFINESPRITE, - TAGID_DEFINEBUTTON, - TAGID_DEFINEBUTTON2, - TAGID_DEFINESOUND, - -1 -}; - -// tags which may be used inside a sprite definition -int spritetagids[] = -{TAGID_SHOWFRAME, - TAGID_PLACEOBJECT, - TAGID_PLACEOBJECT2, - TAGID_REMOVEOBJECT, - TAGID_REMOVEOBJECT2, //? - TAGID_DOACTION, - TAGID_STARTSOUND, - TAGID_FRAMELABEL, - TAGID_SOUNDSTREAMHEAD, - TAGID_SOUNDSTREAMHEAD2, - TAGID_SOUNDSTREAMBLOCK, - TAGID_END, - -1 -}; - -int getidfromtag(struct swf_tag* tag) -{ - int num = 1; - switch(tag->id) { - case TAGID_PLACEOBJECT2: - num++; - case TAGID_PLACEOBJECT: { - struct reader_t r; - reader_init (&r, tag->data, tag->length); - if(num>=2) { - char b = reader_readu8(&r); - if(!(b&2)) - return -1; - } - reader_readu16(&r); - return reader_readu16(&r); - } - break; - case TAGID_REMOVEOBJECT: - return tag->data[0]+tag->data[1]*256; - break; - case TAGID_REMOVEOBJECT2: - return -1; - break; - } - - return tag->data[0]+tag->data[1]*256; -} - -void setidintag(struct swf_tag* tag, int id) -{ - tag->data[0] = id; - tag->data[1] = id>>8; -} - -char is_sprite_tag (int id) -{ - int t=0; - while(spritetagids[t]>=0) - { - if(spritetagids[t] == id) - return 1; - t++; - } - return 0; -} - -char is_defining_tag (int id) -{ - int t=0; - while(definingtagids[t]>=0) - { - if(definingtagids[t] == id) - return 1; - t++; - } - return 0; -} - -struct swf_tag* duptag(struct swf_tag*tag) -{ - struct swf_tag* newtag = (struct swf_tag*)malloc(sizeof(struct swf_tag)); - newtag->id = tag->id; - newtag->fulldata = (u8*)malloc(tag->fulllength); - newtag->fulllength = tag->fulllength; - newtag->data = newtag->fulldata + (tag->data - tag->fulldata); - newtag->length = tag->length; - memcpy(newtag->fulldata, tag->fulldata, tag->fulllength); - return newtag; -} - diff --git a/src/flash.h b/src/flash.h deleted file mode 100644 index e518b73..0000000 --- a/src/flash.h +++ /dev/null @@ -1,204 +0,0 @@ -/* flash.h - Header file for flash.c - - Part of the swftools package. - - Copyright (c) 2001 Matthias Kramm - - This file is distributed under the GPL, see file COPYING for details */ - -#ifndef __flash_h__ -#define __flash_h__ - -#include "types.h" -#include "../lib/rfxswf.h" -#include "../lib/log.h" - -#define TAGID_END 0 -#define TAGID_SHOWFRAME 1 -#define TAGID_DEFINESHAPE 2 -#define TAGID_PLACEOBJECT 4 -#define TAGID_REMOVEOBJECT 5 -#define TAGID_DEFINEBITS 6 -#define TAGID_DEFINEBUTTON 7 -#define TAGID_JPEGTABLES 8 -#define TAGID_BACKGROUNDCOLOR 9 -#define TAGID_DEFINEFONT 10 -#define TAGID_DEFINETEXT 11 -#define TAGID_DOACTION 12 -#define TAGID_DEFINEFONTINFO 13 -#define TAGID_DEFINESOUND 14 -#define TAGID_STARTSOUND 15 -#define TAGID_DEFINEBUTTONSOUND 17 -#define TAGID_SOUNDSTREAMHEAD 18 -#define TAGID_SOUNDSTREAMHEAD2 18 -#define TAGID_SOUNDSTREAMBLOCK 19 -#define TAGID_DEFINEBITSLOSSLESS 20 -#define TAGID_DEFINEBITSJPEG2 21 -#define TAGID_DEFINESHAPE2 22 -#define TAGID_DEFINEBUTTONCXFORM 23 -#define TAGID_PROTECT 24 -#define TAGID_PLACEOBJECT2 26 -#define TAGID_REMOVEOBJECT2 28 -#define TAGID_DEFINESHAPE3 32 -#define TAGID_DEFINETEXT2 33 -#define TAGID_DEFINEBUTTON2 34 -#define TAGID_DEFINEBITSJPEG3 35 -#define TAGID_DEFINEBITSLOSSLESS2 36 -#define TAGID_DEFINEEDITTEXT 37 -#define TAGID_DEFINEMOVIE 38 -#define TAGID_DEFINESPRITE 39 -#define TAGID_FRAMELABEL 43 -#define TAGID_DEFINEMORPHSHAPE 46 -#define TAGID_DEFINEFONT2 48 -#define TAGID_EXPORTASSETS 56 -#define TAGID_IMPORTASSETS 57 -#define TAGID_ENABLEDEBUGGER 58 - -#include "bitio.h" - -struct swf_tag; -struct RECT; -struct RGB; -struct MATRIX; -struct CXFORM; -struct CLIPACTIONS; - -struct swf_tag -{ - u16 id; - u32 length; - u8*data; - u32 fulllength; // includes id - u8*fulldata; // likewise -}; - -struct RGB -{ - byte r,g,b; -}; - -struct RGBA -{ - byte r,g,b,a; -}; - -struct RECT -{ - int x1, y1, x2, y2; -}; - -struct MATRIX -{ - u8 hasscale; - u8 hasrotate; - float a[2][2]; - int b[2]; -}; - -struct CXFORM -{ - u8 hasadd; - u8 hasmult; - float rmult, gmult, bmult, amult; - float radd, gadd, badd, aadd; - u8 alpha; -}; - -struct GRADIENT -{ - int num; - u8 ratios[8]; - struct RGB rgb[8]; - struct RGBA rgba[8]; -}; - -struct RECT readRECT(); -struct RGB readRGB(); -struct MATRIX readMATRIX(); -unsigned char* readSTRING(); -struct CLIPACTIONS readCLIPACTIONS(); - -void writeRECT(u8**pos, struct RECT*r); - -void swf_init(struct reader_t*,uchar*newdata, int newlength); -void MATRIX_init(struct MATRIX*m); - -struct flash_header -{ - int version; - u32 length; - struct RECT boundingBox; - u16 rate; - u16 count; - - u8*headerdata; - int headerlength; -}; - -struct swffile -{ - struct flash_header header; - int tagnum; - struct swf_tag* tags; -}; - -struct flash_header swf_read_header(struct reader_t*); -struct RGB readRGB(struct reader_t*); -struct RGBA readRGBA(struct reader_t*); -struct GRADIENT readGRADIENT(struct reader_t*,int shape); -struct RECT readRECT(struct reader_t*); -struct CXFORM readCXFORM(struct reader_t*,char alpha); -struct MATRIX readMATRIX(struct reader_t*); -unsigned char* readSTRING(struct reader_t*); -int swf_read_tag(struct reader_t*,struct swf_tag* swftag); -int swf_count_tags(struct reader_t*); - - -struct PlaceObject -{ - u16 id; - u16 depth; - struct MATRIX matrix; - struct CXFORM cxform; - u8 hascxform; -}; - -struct PlaceObject2 -{ - u8 reserved; - u8 hasclipactions; - u8 hasname; - u8 hasratio; - u8 hascolortransform; - u8 hasmatrix; - u8 hascharacter; - u8 hasmove; - - u16 depth; - int id; - struct MATRIX matrix; - struct CXFORM cxform; - u16 ratio; - char * name; - u16 clipactions; -}; - - -void placeobject_init (struct PlaceObject*obj, struct swf_tag*tag); -void placeobject_write (struct PlaceObject*obj, struct writer_t*w); - -void placeobject2_init (struct PlaceObject2*obj, struct swf_tag*tag); -void placeobject2_write (struct PlaceObject2*obj, struct writer_t*w); - -void read_swf(struct swffile*swf, uchar*data, int length); - -int getidfromtag(struct swf_tag* tag); -void setidintag(struct swf_tag* tag, int id); -char is_sprite_tag (int id); -char is_defining_tag (int id); -struct swf_tag* duptag(struct swf_tag*tag); - -void swf_write_header(struct writer_t*w, struct flash_header*head); - -#endif //__flash_h__ diff --git a/src/reloc.c b/src/reloc.c deleted file mode 100644 index 00983b6..0000000 --- a/src/reloc.c +++ /dev/null @@ -1,426 +0,0 @@ -/* reloc.h - Implements swf_relocate(), which changes the id range of a swf file in - memory. - - Part of the swftools package. - - Copyright (c) 2001 Matthias Kramm - - This file is distributed under the GPL, see file COPYING for details */ - -#include "flash.h" -#include "../lib/rfxswf.h" - -static struct swffile file; - -int slaveids[65536]; - -void maponeid(void*idpos) -{ - u16*idptr = (u16*)idpos; - U16 id = GET16(idptr); - if(slaveids[id]<0) { - logf(" Trying to map id never encountered before: id=%d", id); - return ; - } - logf(" mapping %d to %d", id, slaveids[id]); - PUT16(idptr, slaveids[id]); -} - - -void mapstyles(struct reader_t*reader, int num, void(*callback)(void*)) -{ - u16 count; - int t; - reader_resetbits(reader); - count = reader_readu8(reader); - if(count == 0xff && num>1) // defineshape2,3 only - count = reader_readu16(reader); - -// printf("%d fillstyles\n", count); - for(t=0;t Unknown fillstyle:0x%02x\n",type); - } - } - reader_resetbits(reader); - count = reader_readu8(reader); // line style array -// printf("%d linestyles\n", count); - if(count == 0xff) - count = reader_readu16(reader); - for(t=0;tid) - { - case TAGID_DEFINEBUTTONCXFORM: { - int t; - struct reader_t reader; - callback(&newtag->data[0]); //button id - reader_init (&reader, newtag->data, newtag->length); - for(t=0;t<4;t++) { - int flags; - callback(&newtag->data[0]); - reader_readu16(&reader); //sound id - flags = reader_readu8(&reader); - if(flags&1) - reader_readu32(&reader); // in point - if(flags&2) - reader_readu32(&reader); // out points - if(flags&4) - reader_readu16(&reader); // loop count - if(flags&8) - { - int npoints = reader_readu8(&reader); - int s; - for(s=0;sdata[0]); //button id - break; - case TAGID_PLACEOBJECT: - callback(&newtag->data[0]); - break; - case TAGID_PLACEOBJECT2: - // only if placeflaghascharacter - if(!(newtag->data[0]&2)) - break; - callback(&newtag->data[3]); - break; - case TAGID_REMOVEOBJECT: - callback(&newtag->data[0]); - break; - case TAGID_STARTSOUND: - callback(&newtag->data[0]); - break; - case TAGID_DEFINESPRITE: { - u8*mem = &newtag->data[4]; - int len = newtag->length-4; - - while(1) { - u8*fmem = mem; - int flen = len; - struct swf_tag sprtag; - struct reader_t reader; - - reader_init (&reader, mem, len); - swf_read_tag (&reader, &sprtag); - - mem = reader_getinputpos(&reader); - len = reader_getinputlength(&reader); - - if(sprtag.id == TAGID_END) - break; - - map_ids_mem (fmem,flen,callback); - } - } - break; - case TAGID_DEFINEBUTTON2: // has some font ids in the button records - num++; - //fallthrough - case TAGID_DEFINEBUTTON: { - struct reader_t reader; - reader_init (&reader, newtag->data, newtag->length); - reader_readu16(&reader); //button id - if(num>1) - { - int offset; - reader_readu8(&reader); //flag - offset = reader_readu16(&reader); //offset - } - while(1) - { - u16 charid; - if(!reader_readu8(&reader)) //flags - break; - charid = GET16(reader_getinputpos(&reader)); - callback(reader_getinputpos(&reader)); - reader_readu16(&reader); //char - reader_readu16(&reader); //layer - reader_resetbits(&reader); - readMATRIX(&reader); - if(num>1) { - reader_resetbits(&reader); - readCXFORM(&reader, 1); - } - } - // ... - } - break; - case TAGID_DEFINEEDITTEXT: { - u8 flags1,flags2; - struct reader_t reader; - reader_init (&reader, newtag->data, newtag->length); - reader_readu16(&reader); //id - readRECT(&reader); //bounding box - reader_resetbits(&reader); - flags1 = reader_readu8(&reader); - flags2 = reader_readu8(&reader); - if(flags1 & 1) - callback(reader_getinputpos(&reader)); - } - break; - case TAGID_DEFINETEXT2: - num ++; - case TAGID_DEFINETEXT: { - int glyphbits, advancebits; - int id; - struct reader_t reader; - reader_init (&reader, newtag->data, newtag->length); - id = reader_readu16(&reader); //id - readRECT(&reader); //bounding box - reader_resetbits(&reader); - readMATRIX(&reader); //matrix - reader_resetbits(&reader); - glyphbits = reader_readu8(&reader); //glyphbits - advancebits = reader_readu8(&reader); //advancebits - while(1) { - u16 flags; - reader_resetbits(&reader); - flags = reader_getbits(&reader, 8); - if(!flags) break; - if(flags & 128) // text style record - { - reader_resetbits(&reader); - if(flags & 8) { // hasfont - callback(reader_getinputpos(&reader)); - id = reader_readu16(&reader); - } - if(flags & 4) { // hascolor - if(num==1) readRGB(&reader); - else readRGBA(&reader); - } - if(flags & 2) { //has x offset - reader_resetbits(&reader); - reader_readu16(&reader); - } - if(flags & 1) { //has y offset - reader_resetbits(&reader); - reader_readu16(&reader); - } - if(flags & 8) { //has height - reader_resetbits(&reader); - reader_readu16(&reader); - } - } else { // glyph record - int t; - reader_resetbits(&reader); - for(t=0;tdata[0]); - break; - - case TAGID_DEFINESHAPE3: // these thingies might have bitmap ids in their fillstyles - num++; //fallthrough - case TAGID_DEFINESHAPE2: - num++; //fallthrough - case TAGID_DEFINESHAPE: { - int fillbits; - int linebits; - struct RECT r; - struct reader_t reader; - //printf("defineshape%d\n", num); - reader_init (&reader, newtag->data, newtag->length); - reader_readu16(&reader); // id; - r = readRECT(&reader); // bounds -// printf("%d shape bounds: %d %d %d %d\n",newtag->id,r.x1,r.y1,r.x2,r.y2); - - mapstyles(&reader, num, callback); - fillbits = reader_getbits(&reader, 4); - linebits = reader_getbits(&reader, 4); - reader_resetbits(&reader); - //printf("%d %d\n", fillbits, linebits); - while(1) { - int flags; - /*printf("data: %02x %02x >%02x< %02x %02x\n", - ((u8*)getinputpos())[-2], - ((u8*)getinputpos())[-1], - ((u8*)getinputpos())[0], - ((u8*)getinputpos())[1], - ((u8*)getinputpos())[2]);*/ - flags = reader_getbits(&reader, 1); - if(!flags) { //style change - flags = reader_getbits(&reader, 5); - //printf("style flags:%02x\n",flags); - if(!flags) - break; - if(flags&1) { //move - int n = reader_getbits(&reader, 5); - //printf("n:%d\n",n); - reader_getbits(&reader, n); //x - reader_getbits(&reader, n); //y - } - if(flags&2) { //fill0 - reader_getbits(&reader, fillbits); - } - if(flags&4) { //fill1 - reader_getbits(&reader, fillbits); - } - if(flags&8) { //linestyle - reader_getbits(&reader, linebits); - } - if(flags&16) { - mapstyles(&reader, num, callback); - fillbits = reader_getbits(&reader, 4); - linebits = reader_getbits(&reader, 4); - } - } else { - flags = reader_getbits(&reader, 1); - //printf("edge:%d\n", flags); - if(flags) { //straight edge - int n = reader_getbits(&reader, 4) + 2; - if(reader_getbits(&reader, 1)) { //line flag - reader_getbits(&reader, n); //delta x - reader_getbits(&reader, n); //delta y - } else { - int v=reader_getbits(&reader, 1); - reader_getbits(&reader, n); //vert/horz - } - } else { //curved edge - int n = reader_getbits(&reader, 4) + 2; - reader_getbits(&reader, n); - reader_getbits(&reader, n); - reader_getbits(&reader, n); - reader_getbits(&reader, n); - } - } - } - } - break; - default: - break; - } -} - -static int*bitmap; - -static int get_free_id() -{ - int t; - for (t=1;t<65536;t++) - { - if(bitmap[t] == -1) - { - bitmap[t] = 1; - return t; - } - } - return -1; -} - -static struct swf_tag* map_ids(struct swf_tag*tag) -{ - map_ids_mem(tag->fulldata, tag->fulllength, maponeid); - return tag; -} - -void swf_relocate (u8*data, int length, int*_bitmap) -{ - int pos; - bitmap = _bitmap; - read_swf(&file, data, length); - memset(slaveids, -1, sizeof(slaveids)); - - pos = 0; - while(file.tags[pos].id != 0) { - struct swf_tag*tag = &file.tags[pos]; - - logf(" relocator: processing tag %02x", tag->id); - map_ids(&file.tags[pos]); - - if(is_defining_tag(tag->id)) - { - int newid; - int id; - - id = getidfromtag(tag); //own id - - if(bitmap[id] < 0) { //free - newid = id; - } - else { - newid = get_free_id(id); - } - bitmap[newid] = 1; - slaveids[id] = newid; - - logf(" relocator: id %d mapped to %d",id, newid); - - setidintag(tag, newid); - - logf(" [reloc] write tag %02x (%d bytes in body)", - tag->id, tag->length); - } - pos++; - } -} - diff --git a/src/reloc.h b/src/reloc.h deleted file mode 100644 index ce849ec..0000000 --- a/src/reloc.h +++ /dev/null @@ -1,15 +0,0 @@ -/* reloc.h - Header file for reloc.c - - Part of the swftools package. - - Copyright (c) 2001 Matthias Kramm - - This file is distributed under the GPL, see file COPYING for details */ - -#ifndef __swf_reallocate__ -#define __swf_reallocate__ -void map_ids_mem(unsigned char*mem, int length, void(*callback)(void*)); -void swf_relocate (unsigned char*data, int length, int*bitmap); -#endif // __swf_reallocate__ - diff --git a/src/swfcombine.c b/src/swfcombine.c index 15061d8..1fad28d 100644 --- a/src/swfcombine.c +++ b/src/swfcombine.c @@ -14,13 +14,34 @@ #include "../lib/rfxswf.h" #include "../lib/args.h" #include "../lib/log.h" -#include "combine.h" -#include "settings.h" -#include "types.h" -#include "flash.h" -#include "reloc.h" #include "../config.h" +struct config_t +{ + char overlay; + char alloctest; + char clip; + char stack; + char stack1; + char antistream; + char dummy; + char zlib; + char cat; + char merge; + char isframe; + int loglevel; + int movex; + int movey; + int sizex; + char hassizex; + int sizey; + char hassizey; + int framerate; + float scalex; + float scaley; +}; +struct config_t config; + char * master_filename = 0; char * master_name = 0; char * slave_filename[128]; @@ -208,300 +229,606 @@ int args_callback_command(char*name, char*val) { void args_callback_usage(char*name) { - printf("Usage: %s [-rXYomlcv] [-f] masterfile] [-xysf] [(name1|#id1)=]slavefile1 .. [-xysf] [(nameN|#idN)=]slavefileN\n", name); + printf("Usage: %s [-rXYomlcv] [-f] masterfile [-xysf] [(name1|#id1)=]slavefile1 .. [-xysf] [(nameN|#idN)=]slavefileN\n", name); printf("OR: %s [-rXYomv] --stack[1] [-xysf] [(name1|#id1)=]slavefile1 .. [-xysf] [(nameN|#idN)=]slavefileN\n", name); printf("OR: %s [-rXYov] --cat [-xysf] [(name1|#id1)=]slavefile1 .. [-xysf] [(nameN|#idN)=]slavefileN\n", name); printf("OR: %s [-rXYomlcv] --dummy [-xys] [file]\n", name); printf("\n"); printf("-o outputfile --output explicitly specify output file. (otherwise, output.swf will be used\n"); - printf("-t --stack place each slave in a seperate frame (no master movie\n"); - printf("-T --stack1 place each slave in the first frame (no master movie\n"); + printf("-t --stack place each slave in a seperate frame (no master movie)\n"); + printf("-T --stack1 place each slave in the first frame (no master movie)\n"); printf("-m --merge Don't store the slaves in Sprites/MovieClips\n"); - printf("-a --cat concatenate all slave files (no master movie\n"); + printf("-a --cat concatenate all slave files (no master movie)\n"); printf("-l --overlay Don't remove any master objects, only overlay new objects\n"); printf("-c --clip Clip the slave objects by the corresponding master objects\n"); printf("-v --verbose Use more than one -v for greater effect \n"); printf("-d --dummy Don't require slave objects \n"); printf("-f --frame The following identifier is a frame or framelabel, not an id or objectname\n"); - printf("-x xpos --movex x Adjust position of slave by xpos twips (1/20 pixel\n"); - printf("-y ypos --movey y Adjust position of slave by ypos twips (1/20 pixel\n"); + printf("-x xpos --movex x Adjust position of slave by xpos twips (1/20 pixel)\n"); + printf("-y ypos --movey y Adjust position of slave by ypos twips (1/20 pixel)\n"); printf("-s scale --scale Adjust size of slave by scale%\n"); - printf("-r framerate --rate Set movie framerate (100 frames/sec\n"); - printf("-X width --width Force movie width to scale (default: use master width (not with -t\n"); - printf("-Y height --height Force movie height to scale (default: use master height (not with -t\n"); + printf("-r framerate --rate Set movie framerate (100 frames/sec)\n"); + printf("-X width --width Force movie width to scale (default: use master width (not with -t))\n"); + printf("-Y height --height Force movie height to scale (default: use master height (not with -t))\n"); printf("-z zlib --zlib Enable Flash 6 (MX) Zlib Compression\n"); } -static void zlib_error(int ret, char* msg, z_stream*zs) +static void makestackmaster(SWF*swf) { - fprintf(stderr, "%s: zlib error (%d): last zlib error: %s\n", - msg, - ret, - zs->msg?zs->msg:"unknown"); - perror("errno:"); - exit(1); -} + TAG*tag; + int t; + SRECT box; + int fileversion = 1; + memset(&box, 0, sizeof(box)); -static char* fi_depack(FILE* fi, unsigned int * setlength) { - char * mem; - z_stream zs; - int ret; - char buffer1[8192], *buffer2; - int memsize = 8192; - int mempos = 0; - memset(&zs,0,sizeof(z_stream)); - zs.zalloc = Z_NULL; - zs.zfree = Z_NULL; - zs.opaque = Z_NULL; - buffer2 = malloc(8192); - - ret = inflateInit(&zs); - if (ret != Z_OK) zlib_error(ret, "inflate_init", &zs); - - fread(buffer2, 8, 1, fi); - buffer2[0] = 'F'; - - zs.next_out = &buffer2[8]; - zs.avail_out = 8192-8; - zs.avail_in = 0; + /* scan all slaves for bounding box */ + for(t=0;t Couldn't open/read %s.", slave_filename[t]); + exit(1); + } + close(fi); + logf(" File %s has bounding box %d:%d:%d:%d\n", + slave_filename[t], + head.movieSize.xmin, head.movieSize.ymin, + head.movieSize.xmax, head.movieSize.ymax); + if(head.fileVersion > fileversion) + fileversion = head.fileVersion; + if(!t) + box = head.movieSize; + else { + if(head.movieSize.xmin < box.xmin) + box.xmin = head.movieSize.xmin; + if(head.movieSize.ymin < box.ymin) + box.ymin = head.movieSize.ymin; + if(head.movieSize.xmax > box.xmax) + box.xmax = head.movieSize.xmax; + if(head.movieSize.ymax > box.ymax) + box.ymax = head.movieSize.ymax; + } + logf(" New master bounding box is %d:%d:%d:%d\n", + box.xmin, box.ymin, + box.xmax, box.ymax); + swf_FreeTags(&head); + } + + memset(swf, 0, sizeof(SWF)); - while(1) + swf->firstTag = swf_InsertTag(tag, ST_SETBACKGROUNDCOLOR); + tag = swf->firstTag; + swf_SetU8(tag, 0); + swf_SetU8(tag, 0); + swf_SetU8(tag, 0); + + for(t=0;tfirstTag; + while(rtag) { + if(!swf_isAllowedSpriteTag(rtag)) { + logf(" processing sprite tag %02x", tag->id); + if(swf_isDefiningTag(rtag)) + { + logf(" [sprite defs] write tag %02x (%d bytes in body)", + tag->id, tag->len); + tag = swf_InsertTag(tag, rtag->id); + swf_SetBlock(tag, rtag->data, rtag->len); + } + else if(swf_isPseudoDefiningTag(rtag)) + { + logf(" [sprite defs] write tag %02x (%d bytes in body)", + tag->id, tag->len); + tag = swf_InsertTag(tag, rtag->id); + swf_SetBlock(tag, rtag->data, rtag->len); + } + else { + switch(rtag->id) + { + case ST_JPEGTABLES: + /* 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 */ + tag = swf_InsertTag(tag, rtag->id); + swf_SetBlock(tag, rtag->data, rtag->len); + break; + case ST_EXPORTASSETS: + logf(" deliberately ignoring EXPORTASSETS tag"); + break; + case ST_ENABLEDEBUGGER: + logf(" deliberately ignoring ENABLEDEBUGGER tag"); + break; + case ST_SETBACKGROUNDCOLOR: + logf(" deliberately ignoring BACKGROUNDCOLOR tag"); + break; + case 40: + case 49: + case 51: + logf(" found tag %d. This is a Generator template, isn't it?", tag->id); + break; + default: + logf(" funny tag: %d is neither defining nor sprite", tag->id); + } + } + } + pos++; } + return tag; +} - mem = malloc(length); - if(!mem) - return 0; - while(!feof(fi)) +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) + PUT16(&tag->data[1],GET16(&tag->data[1])+add); + if(tag->id == ST_REMOVEOBJECT) + PUT16(&tag->data[2],GET16(&tag->data[2])+add); + if(tag->id == ST_REMOVEOBJECT2) + PUT16(&tag->data[0],GET16(&tag->data[0])+add); +} + +void matrix_adjust(MATRIX*m) +{ + m->sx = (int)(m->sx*config.scalex); + m->sy = (int)(m->sy*config.scaley); + m->r0 = (int)(m->r0*config.scalex); + m->r1 = (int)(m->r1*config.scaley); + m->tx += config.movex; + m->ty += config.movey; +} + +void write_changepos(TAG*output, TAG*tag) +{ + if(config.movex || config.movey || config.scalex != 1 || config.scaley != 1) + { + switch(tag->id) + { + case ST_PLACEOBJECT2: { + MATRIX m; + U8 flags; + swf_GetMatrix(0, &m); + + flags = swf_GetU8(tag); + swf_SetU8(output, flags|4); + swf_SetU16(output, swf_GetU16(tag)); //depth + //flags&1: move + if(flags&2) { + swf_SetU16(output, swf_GetU16(tag)); //id + } + if(flags&4) { + swf_GetMatrix(tag, &m); + matrix_adjust(&m); + swf_SetMatrix(tag, &m); + } + swf_SetBlock(output, &tag->data[tag->pos], tag->len - tag->pos); + break; + } + case ST_PLACEOBJECT: { + MATRIX m; + swf_SetU16(output, swf_GetU16(tag)); //id + swf_SetU16(output, swf_GetU16(tag)); //depth + swf_GetMatrix(tag, &m); + matrix_adjust(&m); + swf_SetMatrix(tag, &m); + swf_SetBlock(output, &tag->data[tag->pos], tag->len - tag->pos); + break; + } + default: + swf_SetBlock(output, tag->data, tag->len); + } + } + else { - pos += fread(&mem[pos], 1, 65536, fi); + swf_SetBlock(output, tag->data, tag->len); } - if (setlength) - *setlength = length; - return mem; } -static void fi_pack(FILE*fi, void*_mem, int length) +TAG* write_sprite(TAG*tag, SWF*sprite, int spriteid, int replaceddefine) { - z_stream zs; - int ret; - char*mem = (char*)_mem; - char buffer[8192]; - memset(&zs,0,sizeof(z_stream)); - zs.zalloc = Z_NULL; - zs.zfree = Z_NULL; - zs.opaque = Z_NULL; - - ret = deflateInit(&zs, 9); - if (ret != Z_OK) zlib_error(ret, "deflate_init", &zs); - - mem[0] = 'C'; - fwrite(mem, 8, 1, fi); - - zs.avail_in = length-8; - zs.next_in = mem+8; - zs.avail_out = 8192; - zs.next_out = buffer; + int pos = 0; + TAG* definespritetag; + TAG* rtag; + int tmp; + + definespritetag = tag = swf_InsertTag(tag, ST_DEFINESPRITE); + swf_SetU16(tag, spriteid); + swf_SetU16(tag, sprite->frameCount); + logf (" sprite id is %d", spriteid); - while(1) + // write slave(2) (body) + tmp = sprite->frameCount; + logf(" %d frames to go",tmp); + + if(config.clip) { + tag = swf_InsertTag(tag, ST_PLACEOBJECT2); + swf_SetU8(tag, 2+64); //flags: character+clipdepth + swf_SetU16(tag, 0); //depth + swf_SetU16(tag, replaceddefine); //id + swf_SetU16(tag, 65535); //clipdepth + } + + if(config.overlay && !config.isframe) { + tag = swf_InsertTag(tag, ST_PLACEOBJECT2); + swf_SetU8(tag, 2); //flags: character + swf_SetU16(tag, 0); //depth + swf_SetU16(tag, replaceddefine); //id + } + + rtag = sprite->firstTag; + while(rtag) { - if(zs.avail_in) - ret = deflate(&zs, Z_NO_FLUSH); - else - ret = deflate(&zs, Z_FINISH); - - if (ret == Z_STREAM_END) - break; - - if (ret != Z_OK) zlib_error(ret, "deflate_sync", &zs); - - if (zs.avail_out == 0) - { - fwrite(buffer, 8192, 1, fi); - zs.next_out = buffer; - zs.avail_out = 8192; + if (swf_isAllowedSpriteTag(rtag)) { + + changedepth(rtag, +1); + logf(" [sprite main] write tag %02x (%d bytes in body)", + rtag->id, rtag->len); + + tag = swf_InsertTag(tag, rtag->id); + write_changepos(rtag, tag); + + if(tag->id == ST_SHOWFRAME) + { + tmp--; + logf(" %d frames to go",tmp); + } } } - fwrite(buffer, zs.next_out - (Bytef*)buffer, 1, fi); - - ret = deflateEnd(&zs); - if (ret != Z_OK) zlib_error(ret, "deflate_end", &zs); + return tag; } -static void fi_dump(FILE*fi, void*_mem, int length) +static char tag_ok_for_slave(int id) { - char*mem = (char*)_mem; - int pos = 0; - while(pos < length) + if(id == ST_SETBACKGROUNDCOLOR) + return 0; + return 1; +} + +TAG* write_master(TAG*tag, SWF*master, SWF*slave, int spriteid, int replaceddefine, int flags) +{ + int outputslave = 0; + int frame = 0; + int sframe = 0; + int slavewritten = 0; + + TAG* rtag = master->firstTag; + TAG* stag = slave->firstTag; + + while(rtag) { - int size = 65536; - if (size > (length - pos)) - size = (length - pos); - pos += fwrite(&mem[pos], 1, size, fi); + if(rtag->id == ST_SHOWFRAME && outputslave) + { + while(stag) { + if(stag->id == ST_SHOWFRAME) { + stag = stag->next; + sframe++; + break; + } + if(tag_ok_for_slave(stag->id)) { + tag = swf_InsertTag(tag, stag->id); + swf_SetBlock(tag, stag->data, stag->len); + } + stag = stag->next; + } + } + if(rtag->id == ST_SHOWFRAME) + { + frame ++; + } + + if(swf_isDefiningTag(rtag) && (flags&FLAGS_WRITEDEFINES)) + { + logf(" [master] write tag %02x (%d bytes in body)", + rtag->id, rtag->len); + if(swf_GetDefineID(rtag) == spriteid && !config.isframe) + { + if(config.overlay) + { + PUT16(rtag->data, replaceddefine); + tag = swf_InsertTag(tag, rtag->id); + swf_SetBlock(tag, rtag->data, rtag->len); + } else { + /* don't write this tag */ + logf(" replacing tag %d id %d with sprite", rtag->id + ,spriteid); + } + + if(flags&FLAGS_WRITESPRITE) + { + tag = write_sprite_defines(tag, slave); + tag = write_sprite(tag, slave, spriteid, replaceddefine); + } + if(flags&FLAGS_WRITESLAVE) + { + outputslave = 1; + } + } else { + tag = swf_InsertTag(tag, rtag->id); + swf_SetBlock(tag, rtag->data, rtag->len); + } + } + if(frame == slaveframe) + { + if(flags&FLAGS_WRITESLAVE) { + outputslave = 1; + slavewritten = 1; + } + if((flags&FLAGS_WRITESPRITE) && !slavewritten) + { + int id = get_free_id(masterbitmap); + int depth = 0; + if(config.clip) { + logf(" Can't combine --clip and --frame"); + } + + tag = write_sprite_defines(tag, slave); + tag = write_sprite(tag, slave, id, -1); + + tag = swf_InsertTag(tag, ST_PLACEOBJECT2); + swf_SetU8(tag, 2); //flags: id + swf_SetU16(tag, depth); + swf_SetU16(tag, id); + + slavewritten = 1; + } + } + if(!swf_isDefiningTag(rtag) && (flags&FLAGS_WRITENONDEFINES)) + { + int dontwrite = 0; + switch(rtag->id) { + case ST_PLACEOBJECT: + case ST_PLACEOBJECT2: + if(frame == slaveframe && !config.overlay) + dontwrite = 1; + case ST_REMOVEOBJECT: +// case ST_REMOVEOBJECT2: + /* place/removetags for the object we replaced + should be discarded, too, as the object to insert + isn't a sprite + */ + if(spriteid>=0 && swf_GetPlaceID(rtag) == spriteid && + !config.isframe && config.merge) + dontwrite = 1; + break; + } + if(!dontwrite) { + logf(" [master] write tag %02x (%d bytes in body)", + rtag->id, rtag->len); + tag = swf_InsertTag(tag, rtag->id); + swf_SetBlock(tag, rtag->data, rtag->len); + } + } + tag = tag->next; } + + if(outputslave) + while(stag) + { + if(tag_ok_for_slave(stag->id)) { + tag = swf_InsertTag(tag, stag->id); + swf_SetBlock(tag, stag->data, stag->len); + } + stag = stag->next; + } + if(!slavewritten && config.isframe && (flags&(FLAGS_WRITESLAVE|FLAGS_WRITESPRITE))) + { + if(slaveframe>=0) + logf(" Frame %d doesn't exist in file. No substitution will occur", + slaveframe); + else + logf(" Frame \"%s\" doesn't exist in file. No substitution will occur", + slavename); + } + return tag; } -/* todo: use rfxswf */ -static void makestackmaster(u8**masterdata, int*masterlength) +void catcombine(SWF*master, char*slave_name, SWF*slave, SWF*newswf) { - u8 head[] = {'F','W','S'}; - u8 *pos; - u32 * fixpos; - int t; - struct RECT box; - int strlength = 0; - int fileversion = 1; + printf("--cat not implemented yet. Please use the swfcombine from swftools 0.3.1 or 0.2.3.\n"); + exit(1); +} - /* scan all slaves for bounding box */ - for(t=0;tfirstTag; + + // set the idtab + pos = 0; + + while(tag) { - FILE*fi=fopen(slave_filename[t],"rb"); - u8 data[256]; - int ret; - struct flash_header head; - struct reader_t r; - strlength += strlen(slave_name[t]) + 9; - if(!fi) { - logf(" Couldn't open %s.", slave_filename[t]); - exit(1); + if(swf_isDefiningTag(tag)) { + int defineid = swf_GetDefineID(tag); + logf(" tagid %02x defines object %d", tag, defineid); + masterbitmap[defineid] = 1; + } else if(tag->id == ST_PLACEOBJECT2) { + char * name = swf_GetName(tag); + int id = swf_GetPlaceID(tag); + + if(name) + logf(" tagid %02x places object %d named \"%s\"", tag, id, name); + else + logf(" tagid %02x places object %d (no name)", tag, id); + + if ((name && slavename && !strcmp(name,slavename)) || + (!slavename && id==slaveid)) { + if(id>=0) { + spriteid = id; + logf(" Slave file attached to object %d.", id); + } + } + } else if(tag->id == ST_SHOWFRAME) { + if(slaveframe>=0 && frame==slaveframe) { + logf(" Slave file attached to frame %d.", frame); + } + frame++; + } else if(tag->id == ST_FRAMELABEL) { + char * name = tag->data; + if(name && slavename && config.isframe && !strcmp(name, slavename)) { + slaveframe = frame; + logf(" Slave file attached to frame %d (%s).", frame, name); + } } - ret = fread(data,1,256,fi); - if(ret < 13) { - logf(" File %s is to small (%d bytes)", slave_filename[t], ret); - exit(1); + }; + + if (spriteid<0 && !config.isframe) { + if(slavename) { + if(strcmp(slavename,"!!dummy!!")) + logf(" Didn't find anything named %s in file. No substitutions will occur.", slavename); } - swf_init(&r, data,256); - head = swf_read_header(&r); - logf(" File %s has bounding box %d:%d:%d:%d\n", - slave_filename[t], - head.boundingBox.x1, head.boundingBox.y1, - head.boundingBox.x2, head.boundingBox.y2); - if(head.version > fileversion) - fileversion = head.version; - if(!t) - box = head.boundingBox; - else { - if(head.boundingBox.x1 < box.x1) - box.x1 = head.boundingBox.x1; - if(head.boundingBox.y1 < box.y1) - box.y1 = head.boundingBox.y1; - if(head.boundingBox.x2 > box.x2) - box.x2 = head.boundingBox.x2; - if(head.boundingBox.y2 > box.y2) - box.y2 = head.boundingBox.y2; + else + logf(" Didn't find id %d in file. No substitutions will occur.", slaveid); + spriteid = get_free_id(masterbitmap); + } + + swf_Relocate (slave, masterbitmap); + jpeg_assert(); + + if (config.overlay) + replaceddefine = get_free_id(masterbitmap); + + // write file + + memcpy(newswf, master, sizeof(SWF)); + newswf->firstTag = tag = swf_InsertTag(0, ST_REFLEX); + + if (config.antistream) { + if (config.merge) { + logf(" Can't combine --antistream and --merge"); } - logf(" New master bounding box is %d:%d:%d:%d\n", - box.x1, box.y1, - box.x2, box.y2); - fclose(fi); - } - - /* we don't have a master, so we create one ourselves. */ - *masterlength = (numslaves + 1) * 32 + strlength; - *masterdata = (u8*)malloc(*masterlength); - pos = *masterdata; - memcpy(pos, head, sizeof(head)); - pos += sizeof(head); - *pos++ = fileversion; - fixpos = (u32*)pos; - PUT32(pos, 0x12345678); // to be overwritten - pos += 4; - writeRECT(&pos, &box); - PUT16(pos, 0x2000) // framerate - pos += 2; - PUT16(pos, numslaves) // framerate - pos += 2; - for(t=0;t=0) { + slaveframe = slaveid; + slaveid = -1; + } else { + /* if id wasn't given as either #number or number, + the name is a frame label. BTW: The user wouldn't have + needed to supply the -f option in this case */ } } - PUT16(pos, ((TAGID_END<<6) + 0)); - *masterlength = pos - *masterdata; - PUT32(fixpos, *masterlength); + + logf(" move x (%d)", config.movex); + logf(" move y (%d)", config.movey); + logf(" scale x (%f)", config.scalex); + logf(" scale y (%f)", config.scaley); + logf(" is frame (%d)", config.isframe); + + memset(masterbitmap, 0, sizeof(masterbitmap)); + + if(config.cat) + return catcombine(master, slave_name, slave, newswf); + else + return normalcombine(master, slave_name, slave, newswf); } -struct config_t config; int main(int argn, char *argv[]) { - FILE*fi; - u8*masterdata; - unsigned int masterlength; - u8*slavedata; - unsigned int slavelength; - u8*newdata; - unsigned int newlength; + int fi; + SWF master; + SWF slave; + SWF newswf; int t; config.overlay = 0; @@ -534,7 +861,6 @@ int main(int argn, char *argv[]) } if(config.stack) { - if(config.overlay) { logf(" Can't combine -l and -t"); exit(1); @@ -545,24 +871,23 @@ int main(int argn, char *argv[]) } logf(" (stacking) %d files found\n", numslaves); - makestackmaster(&masterdata,&masterlength); - - logf(" Generated %d bytes of master data", masterlength); + makestackmaster(&master); } else { + int ret; logf(" master entity %s (named \"%s\")\n", master_filename, master_name); - fi = fopen(master_filename, "rb"); - if(!fi) { + fi = open(master_filename, O_RDONLY); + if(fi<0) { logf(" Failed to open %s\n", master_filename); exit(1); } - masterdata = fi_slurp(fi, &masterlength); - if(!masterdata) { + ret = swf_ReadSWF(fi, &master); + if(ret<0) { logf(" Failed to read from %s\n", master_filename); exit(1); } - logf(" Read %d bytes from masterfile\n", masterlength); - fclose(fi); + logf(" Read %d bytes from masterfile\n", ret); + close(fi); } for(t=0;t You must have at least one slave entity."); + if(config.cat) + logf(" You must have at least two objects."); + else + logf(" You must have at least one slave entity."); return 0; } for(t = 0; t < numslaves; t++) @@ -612,55 +940,40 @@ int main(int argn, char *argv[]) slave_name[t], slave_filename[t]); if(!config.dummy) { - fi = fopen(slave_filename[t], "rb"); + int ret; + fi = open(slave_filename[t], O_RDONLY); if(!fi) { logf(" Failed to open %s\n", slave_filename[t]); exit(1); } - slavedata = fi_slurp(fi, &slavelength); - if(!slavedata) { + ret = swf_ReadSWF(fi, &slave); + if(ret<0) { logf(" Failed to read from %s\n", slave_filename[t]); exit(1); } - logf(" Read %d bytes from slavefile\n", slavelength); - fclose(fi); + logf(" Read %d bytes from slavefile\n", ret); + close(fi); } else { - slavedata = (u8*)malloc(16); - slavedata[0] = 'F'; - slavedata[1] = 'W'; - slavedata[2] = 'S'; - slavedata[3] = 4; //version - PUT32(&slavedata[4], 14); ; // length - slavedata[8] = 0; // boundingbox - PUT16(&slavedata[9] , (0)); // rate - PUT16(&slavedata[11] , (0)); // count - PUT16(&slavedata[13] , (0)); // end tag - slavelength = 17; + memset(&slave, 0, sizeof(slave)); + slave.firstTag = swf_InsertTag(0, ST_END); + slave.frameRate = 0; + slave.fileVersion = 4; + slave.frameCount = 0; } - newdata = combine(masterdata, masterlength, slave_name[t], slavedata, slavelength, &newlength); - if(!newdata) { - logf(" Aborting."); - return 1; - } - - free(masterdata); - masterdata = newdata; - masterlength = newlength; + combine(&master, slave_name[t], &slave, &newswf); + master = newswf; } } - logf(" New File is %d bytes \n", newlength); - if(newdata && newlength) { - FILE*fi = fopen(outputname, "wb"); - if(config.zlib) - fi_pack(fi, newdata, newlength); - else - fi_dump(fi, newdata, newlength); - fclose(fi); - } + fi = open(outputname, O_RDWR|O_TRUNC|O_CREAT); + if(config.zlib) + swf_WriteSWC(fi, &newswf); + else + swf_WriteSWF(fi, &newswf); + close(fi); return 0; }