Example #1
0
void swf_FontPostprocess(SWF*swf)
{
    TAG*tag = swf->firstTag;
    while(tag) {
	TAG*next = tag->next;
	if(tag->id == ST_DEFINEFONT3) {
	    U16 id = swf_GetDefineID(tag);
	    SWFFONT*font = 0;
	    swf_FontExtract(swf, id, &font);
	    if(!font->alignzones) {
		swf_FontCreateAlignZones(font);
		tag = swf_InsertTag(tag, ST_DEFINEFONTALIGNZONES);
		swf_FontSetAlignZones(tag, font);
	    }
	    swf_FontFree(font);
	}
	tag = next;
    }
}
Example #2
0
int catcombine(SWF*master, char*slave_name, SWF*slave, SWF*newswf)
{
    char* depths;
    int t;
    TAG*tag;
    TAG*mtag,*stag;
    if(config.isframe) {
		msg("<fatal> Can't combine --cat and --frame");
		return 101;
    }
    if(config.flashversion)
	master->fileVersion = config.flashversion;
   
    tag = master->firstTag;
    while(tag)
    {
	if(swf_isDefiningTag(tag)) {
	    int defineid = swf_GetDefineID(tag);
	    msg("<debug> tagid %02x defines object %d", tag->id, defineid);
	    masterbitmap[defineid] = 1;
	}
	tag = tag->next;
    }
    
    swf_Relocate(slave, masterbitmap);
    jpeg_assert(master, slave);
    
    memcpy(newswf, master, sizeof(SWF));
    adjustheader(newswf);

    tag = newswf->firstTag = swf_InsertTag(0, ST_REFLEX); // to be removed later

    depths = malloc_safe(65536);
    if(!depths) {
	msg("<fatal> Couldn't allocate %d bytes of memory", 65536);
	return 111;
    }
    memset(depths, 0, 65536);
    mtag = master->firstTag;
    while(mtag && mtag->id!=ST_END)
    {
	int num=1;
	U16 depth;
	msg("<debug> [master] write tag %02x (%d bytes in body)", 
		mtag->id, mtag->len);
	switch(mtag->id) {
	    case ST_PLACEOBJECT2:
		num++;
	    case ST_PLACEOBJECT: {
	       depth = swf_GetDepth(mtag);
	       depths[depth] = 1;
	    }
	    break;
	    case ST_REMOVEOBJECT: {
	       depth = swf_GetDepth(mtag);
	       depths[depth] = 0;
	    }
	    break;
	    case ST_REMOVEOBJECT2: {
	       depth = swf_GetDepth(mtag);
	       depths[depth] = 0;
	    }
	    break;
	}
	tag = swf_InsertTag(tag, mtag->id);
	swf_SetBlock(tag, mtag->data, mtag->len);

	mtag = mtag->next;
    }

    for(t=0;t<65536;t++) 
    if(depths[t])
    {
	char data[16];
	int len;
	tag = swf_InsertTag(tag, ST_REMOVEOBJECT2);
	swf_SetU16(tag, t);
    }
    free(depths);

    stag = slave->firstTag;
    while(stag && stag->id!=ST_END)
    {
	msg("<debug> [slave] write tag %02x (%d bytes in body)", 
		stag->id, stag->len);
	tag = swf_InsertTag(tag, stag->id);
	swf_SetBlock(tag, stag->data, stag->len);
	stag = stag->next;
    }
    tag = swf_InsertTag(tag, ST_END);

    swf_DeleteTag(newswf, tag);

	return 0;
}
Example #3
0
int normalcombine(SWF*master, char*slave_name, SWF*slave, SWF*newswf)
{
    int spriteid = -1;
    int replaceddefine = -1;
    int frame = 0;
    char*framelabel;
    TAG * tag = master->firstTag;

    memset(depthbitmap, 0, sizeof(depthbitmap));
    
    // set the idtab
    while(tag)
    {
	int depth = swf_GetDepth(tag);
	if(depth>=0) {
	    depthbitmap[depth] = 1;
	}
	if(swf_isDefiningTag(tag)) {
	    int defineid = swf_GetDefineID(tag);
	    msg("<debug> tagid %02x defines object %d", tag->id, defineid);
	    masterbitmap[defineid] = 1;

	    if (!slavename && defineid==slaveid) {
		if(defineid>=0) {
		  spriteid = defineid;
		  msg("<notice> Slave file attached to object %d.", defineid);
		}
	    }
	} else if(tag->id == ST_EXPORTASSETS) {
	    int t;
	    int num = swf_GetU16(tag);
	    for(t=0;t<num;t++)
	    {
		U16 id = swf_GetU16(tag);
		char*name = swf_GetString(tag);
		if(spriteid<0 && slavename && !strcmp(name,slavename)) {
		    spriteid = id;
		    msg("<notice> Slave file attached to object %d exported as %s.", id, name);
		}
	    }
	} else if(tag->id == ST_SYMBOLCLASS) {
	    /* a symbolclass tag is like a define tag: it defines id 0000 */
	    int num = swf_GetU16(tag);
	    int t;
	    for(t=0;t<num;t++) {
		U16 id = swf_GetU16(tag);
		if(!id) {
		    masterbitmap[id] = 1;
		}
		swf_GetString(tag);
	    }
	} else if(tag->id == ST_PLACEOBJECT2) {
	    char * name = swf_GetName(tag);
	    int id = swf_GetPlaceID(tag);

	    {
		SWFPLACEOBJECT obj;
		swf_GetPlaceObject(tag, &obj);
		swf_PlaceObjectFree(&obj);
		if(obj.clipdepth) {
		    depthbitmap[obj.clipdepth] = 1;
		}
	    }

	    if(name)
	      msg("<verbose> tagid %02x places object %d named \"%s\"", tag->id, id, name);
	    else
	      msg("<verbose> tagid %02x places object %d (no name)", tag->id, id);

	    if (name && slavename && !strcmp(name,slavename)) {
		if(id>=0) {
		  spriteid = id;
		  msg("<notice> Slave file attached to named object %s (%d).", name, id);
		}
	    }
	} else if(tag->id == ST_SHOWFRAME) {
	    if(slaveframe>=0 && frame==slaveframe) {
		msg("<notice> Slave file attached to frame %d.", frame);
	    }
	    frame++;
	} else if(tag->id == ST_FRAMELABEL) {
	    char * name = (char *)tag->data;
	    if(name && slavename && config.isframe && !strcmp(name, slavename)) {
		slaveframe = frame;
		msg("<notice> Slave file attached to frame %d (%s).", frame, name);
	    }
	}
	tag = tag->next;
    };

    if (spriteid<0 && !config.isframe) {
	if(slavename) {
	    if(strcmp(slavename,"!!dummy!!")) {
		msg("<warning> Didn't find anything named %s in file. No substitutions will occur.", slavename);
		if(!strcmp(slavename, "swf")) {
		    msg("<warning> (If you were trying to combine rfxview with a document, try replacing 'swf' with 'viewport'.");
		}
	    }
	}
	else
	    msg("<warning> Didn't find id %d in file. No substitutions will occur.", slaveid);
	spriteid = get_free_id(masterbitmap);
    }

    swf_Relocate (slave, masterbitmap);
    
    if(config.merge)
	swf_RelocateDepth (slave, depthbitmap);
    jpeg_assert(slave, master);
    
    if (config.overlay)
	replaceddefine = get_free_id(masterbitmap);
    
    // write file 

    memcpy(newswf, master, sizeof(SWF));
    adjustheader(newswf);

    newswf->firstTag = tag = swf_InsertTag(0, ST_REFLEX); // to be removed later

    if (config.antistream) {
	if (config.merge) {
	    msg("<fatal> Can't combine --antistream and --merge");
	}
	tag = write_sprite_defines(tag, slave);
	tag = write_sprite(tag, slave, spriteid, replaceddefine);
	tag = write_master(tag, master, slave, spriteid, replaceddefine, FLAGS_WRITEDEFINES);
	tag = write_master(tag, master, slave, spriteid, replaceddefine, FLAGS_WRITENONDEFINES);
    } else {
	if (config.merge)
	    tag = write_master(tag, master, slave, spriteid, replaceddefine, 
		FLAGS_WRITEDEFINES|FLAGS_WRITENONDEFINES|   FLAGS_WRITESLAVE	);
	else
	    tag = write_master(tag, master, slave, spriteid, replaceddefine, 
		FLAGS_WRITEDEFINES|FLAGS_WRITENONDEFINES|   FLAGS_WRITESPRITE	);
    }

    swf_DeleteTag(newswf, newswf->firstTag);

	return 0;
}
Example #4
0
TAG* write_master(TAG*tag, SWF*master, SWF*slave, int spriteid, int replaceddefine, int flags)
{
    int outputslave = 0;
    int frame = 1;
    int sframe = 0;
    int slavewritten = 0;
    int deletedepth = -1;

    TAG* rtag = master->firstTag;
    TAG* stag = slave->firstTag;

    while(rtag && rtag->id!=ST_END)
    {
	if(rtag->id == ST_SHOWFRAME && outputslave)
	{
	    while(stag && stag->id!=ST_END) {
		if(stag->id == ST_SHOWFRAME) {
		    stag = stag->next;
		    sframe++;
		    break;
		}
		if(tag_ok_for_slave(stag->id)) {
		    tag = swf_InsertTag(tag, stag->id);
		    write_changepos(tag, stag, config.movex, config.movey, config.scalex, config.scaley, 0);
		}
		stag = stag->next;
	    }
	}
	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))
	{
	    msg("<debug> [master] write tag %02x (%d bytes in body)", 
		    rtag->id, rtag->len);
	    if(swf_GetDefineID(rtag) == spriteid && !config.isframe)
	    {
		if(config.overlay)
		{
		    tag = swf_InsertTag(tag, rtag->id);
		    swf_SetBlock(tag, rtag->data, rtag->len);
		    swf_SetDefineID(tag, replaceddefine);
		} else {
		    /* don't write this tag */
		    msg("<verbose> replacing tag %d ID %d with sprite", rtag->id ,spriteid);
		}

		if(flags&FLAGS_WRITESPRITE)
		{
		    msg("<debug> writing sprite defines");
		    tag = write_sprite_defines(tag, slave);
		    msg("<debug> writing sprite");
		    tag = write_sprite(tag, slave, spriteid, replaceddefine);
		}
		if(flags&FLAGS_WRITESLAVE)
		{
		    msg("<debug> writing slave");
		    outputslave = 1;
		}
	    } else { 
		tag = swf_InsertTag(tag, rtag->id);
		swf_SetBlock(tag, rtag->data, rtag->len);
	    }
	}
	if(frame == slaveframe) /* only happens with config.isframe: put slave at specific frame */
	{
	    if(flags&FLAGS_WRITESLAVE) {
		outputslave = 1;
		slavewritten = 1;
	    }
	    if((flags&FLAGS_WRITESPRITE) && !slavewritten)
	    {
		int id = get_free_id(masterbitmap);
		int depth = 65535;
		deletedepth = 65535;
		if(config.clip) {
		    msg("<fatal> 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:
		    /* 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;
		case ST_REMOVEOBJECT2:
		break;
	    }
	    if(!dontwrite) {
		msg("<debug> [master] write tag %02x (%d bytes in body)", 
			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;
    }
   
    if(outputslave) 
    while(stag && stag->id!=ST_END)
    {
	    if(tag_ok_for_slave(stag->id)) {
		msg("<debug> [slave] write tag %02x (%d bytes in body), %.2f %.2f", rtag->id, rtag->len, config.movex /20.0, config.movey /20.0);
		tag = swf_InsertTag(tag, stag->id);
		write_changepos(tag, stag, config.movex, config.movey, config.scalex, config.scaley, 0);
	    }
	    stag = stag->next;
    }
    if(!slavewritten && config.isframe && (flags&(FLAGS_WRITESLAVE|FLAGS_WRITESPRITE)))
    {
	if(slaveframe>=0)
	    msg("<warning> Frame %d doesn't exist in file. No substitution will occur",
		    slaveframe);
	else
	    msg("<warning> Frame \"%s\" doesn't exist in file. No substitution will occur",
		    slavename);
    }
    tag = swf_InsertTag(tag, ST_END);
    return tag;
}
void swf_AddButtonLinks(SWF*swf, char stop_each_frame, char events)
{
    int num_frames = 0;
    int has_buttons = 0;
    TAG*tag=swf->firstTag;

    unsigned int checksum = 0;
    while(tag) {
        if(tag->id == ST_SHOWFRAME)
            num_frames++;
        if(tag->id == ST_DEFINEBUTTON || tag->id == ST_DEFINEBUTTON2)
            has_buttons = 1;
	crc32_add_bytes(checksum, tag->data, tag->len);
        tag = tag->next;
    }
    int t = time(0);
    checksum = crc32_add_bytes(checksum, &t, sizeof(t));

    unsigned char h[16];
    unsigned char file_signature[33];
    sprintf((char*)file_signature, "%x", checksum);

    char scenename1[80], scenename2[80];
    sprintf(scenename1, "rfx.MainTimeline_%s", file_signature);
    sprintf(scenename2, "rfx::MainTimeline_%s", file_signature);

    abc_file_t*file = abc_file_new();
    abc_method_body_t*c = 0;
   
    abc_class_t*cls = abc_class_new2(file, scenename2, "flash.display::MovieClip");
  
    TAG*abctag = swf_InsertTagBefore(swf, swf->firstTag, ST_DOABC);
    
    tag = swf_InsertTag(abctag, ST_SYMBOLCLASS);
    swf_SetU16(tag, 1);
    swf_SetU16(tag, 0);
    swf_SetString(tag, scenename1);

    c = abc_class_getstaticconstructor(cls, 0)->body;
    c->old.max_stack = 1;
    c->old.local_count = 1;
    c->old.init_scope_depth = 9;
    c->old.max_scope_depth = 10;

    __ getlocal_0(c);
    __ pushscope(c);
    __ returnvoid(c);

    c = abc_class_getconstructor(cls, 0)->body;
    c->old.max_stack = 3;
    c->old.local_count = 1;
    c->old.init_scope_depth = 10;
    c->old.max_scope_depth = 11;
    
    debugfile(c, "constructor.as");

    __ getlocal_0(c);
    __ pushscope(c);

    __ getlocal_0(c);
    __ constructsuper(c,0);

    if(stop_each_frame || has_buttons) {
        int frame = 0;
        tag = swf->firstTag;
        abc_method_body_t*f = 0; //frame script
        while(tag && tag->id!=ST_END) {
            char framename[80];
            char needs_framescript=0;
            char buttonname[80];
            char functionname[80];
            sprintf(framename, "[packageinternal]rfx::frame%d_%s", frame, file_signature);
            
            if(!f && (tag->id == ST_DEFINEBUTTON || tag->id == ST_DEFINEBUTTON2 || stop_each_frame)) {
                /* make the contructor add a frame script */
                __ findpropstrict(c,"[package]::addFrameScript");
                __ pushuint(c,frame);
                __ getlex(c,framename);
                __ callpropvoid(c,"[package]::addFrameScript",2);

                f = abc_class_method(cls, 0, multiname_fromstring(framename))->body;
                f->old.max_stack = 3;
                f->old.local_count = 1;
                f->old.init_scope_depth = 10;
                f->old.max_scope_depth = 11;
                __ debugfile(f, "framescript.as");
                __ debugline(f, 1);
                __ getlocal_0(f);
                __ pushscope(f);
                if(stop_each_frame) {
                    __ findpropstrict(f, "[package]::stop");
                    __ callpropvoid(f, "[package]::stop", 0);
                }
            }

            if(tag->id == ST_DEFINEBUTTON || tag->id == ST_DEFINEBUTTON2) {
                U16 id = swf_GetDefineID(tag);
                sprintf(buttonname, "::button%d", swf_GetDefineID(tag));
                __ getlex(f,buttonname);
                __ getlex(f,"flash.events::MouseEvent");
                __ getproperty(f, "::CLICK");
                sprintf(functionname, "::clickbutton%d_%s", swf_GetDefineID(tag), file_signature);
                __ getlex(f,functionname);
                __ callpropvoid(f, "::addEventListener" ,2);

                needs_framescript = 1;

                abc_method_body_t*h =
                    abc_class_method(cls, 0, multiname_fromstring(functionname))->body;
                list_append(h->method->parameters, multiname_fromstring("flash.events::MouseEvent"));

                h->old.max_stack = 6;
                h->old.local_count = 2;
                h->old.init_scope_depth = 10;
                h->old.max_scope_depth = 11;
                __ getlocal_0(h);
                __ pushscope(h);

                ActionTAG*oldaction = swf_ButtonGetAction(tag);
                if(oldaction && oldaction->op == ACTION__GOTOFRAME) {
                    int framenr = GET16(oldaction->data);
                    if(!events) {
                        __ findpropstrict(h,"[package]::gotoAndStop");
                        __ pushuint(h,framenr+1);
                        __ callpropvoid(h,"[package]::gotoAndStop", 1);
                    } else {
                        char framename[80];
                        sprintf(framename, "frame%d_%s", framenr, file_signature);
                        __ getlocal_0(h); //this
                        __ findpropstrict(h, "[package]flash.events::TextEvent");
                        __ pushstring(h, "link");
                        __ pushtrue(h);
                        __ pushtrue(h);
                        __ pushstring(h, framename);
                        __ constructprop(h,"[package]flash.events::TextEvent", 4);
                        __ callpropvoid(h,"[package]::dispatchEvent", 1);
                    }
                } else if(oldaction && oldaction->op == ACTION__GETURL) {
                    if(!events) {
                        __ findpropstrict(h,"flash.net::navigateToURL");
                        __ findpropstrict(h,"flash.net::URLRequest");
                        // TODO: target _blank
                        __ pushstring(h,(char*)oldaction->data); //url
                        __ constructprop(h,"flash.net::URLRequest", 1);
                        __ callpropvoid(h,"flash.net::navigateToURL", 1);
                    } else {
                        __ getlocal_0(h); //this
                        __ findpropstrict(h, "[package]flash.events::TextEvent");
                        __ pushstring(h, "link");
                        __ pushtrue(h);
                        __ pushtrue(h);
                        __ pushstring(h,(char*)oldaction->data); //url
                        __ constructprop(h,"[package]flash.events::TextEvent", 4);
                        __ callpropvoid(h,"[package]::dispatchEvent", 1);
                    }
                } else if(oldaction) {
                    fprintf(stderr, "Warning: Couldn't translate button code of button %d to flash 9 abc action\n", id);
                }
                __ returnvoid(h);
                swf_ActionFree(oldaction);
            }
            if(tag->id == ST_SHOWFRAME) {
                if(f) {
                    __ returnvoid(f);
                    f = 0;
                }
                frame++;
            }
            tag = tag->next;
        }
        if(f) {
            __ returnvoid(f);
        }
    }
    __ returnvoid(c);

    tag = swf->firstTag;
    while(tag) {
        if(tag->id == ST_DEFINEBUTTON || tag->id == ST_DEFINEBUTTON2) {
            char buttonname[80];
            sprintf(buttonname, "::button%d", swf_GetDefineID(tag));
            multiname_t*s = multiname_fromstring(buttonname);
            //abc_class_slot(cls, multiname_fromstring(buttonname), s);
            abc_class_slot(cls, multiname_fromstring(buttonname), 
                                multiname_fromstring("flash.display::SimpleButton"));
        }
        tag = tag->next;
    }


    abc_script_t*s = abc_initscript(file);
    c = s->method->body;
    c->old.max_stack = 2;
    c->old.local_count = 1;
    c->old.init_scope_depth = 1;
    c->old.max_scope_depth = 9;

    __ getlocal_0(c);
    __ pushscope(c);
    __ getscopeobject(c, 0);
    __ getlex(c,"::Object");
    __ pushscope(c);
    __ getlex(c,"flash.events::EventDispatcher");
    __ pushscope(c);
    __ getlex(c,"flash.display::DisplayObject");
    __ pushscope(c);
    __ getlex(c,"flash.display::InteractiveObject");
    __ pushscope(c);
    __ getlex(c,"flash.display::DisplayObjectContainer");
    __ pushscope(c);
    __ getlex(c,"flash.display::Sprite");
    __ pushscope(c);
    __ getlex(c,"flash.display::MovieClip");
    __ pushscope(c);
    __ getlex(c,"flash.display::MovieClip");
    __ newclass(c,cls);
    __ popscope(c);
    __ popscope(c);
    __ popscope(c);
    __ popscope(c);
    __ popscope(c);
    __ popscope(c);
    __ popscope(c);
    __ initproperty(c,scenename2);
    __ returnvoid(c);

    //abc_method_body_addClassTrait(c, "rfx:MainTimeline", 1, cls);
    multiname_t*classname = multiname_fromstring(scenename2);
    abc_initscript_addClassTrait(s, classname, cls);
    multiname_destroy(classname);

    swf_WriteABC(abctag, file);
}