示例#1
0
FILTER*swf_GetFilter(TAG*tag)
{
    U8 type = swf_GetU8(tag);
    FILTER*filter;
    if(type == FILTERTYPE_BLUR) {
	FILTER_BLUR* f = (FILTER_BLUR*)rfx_calloc(sizeof(FILTER_BLUR));
	f->type = type;
	f->blurx = swf_GetFixed(tag);
	f->blury = swf_GetFixed(tag);
	U8 flags = swf_GetU8(tag);
	f->passes = (flags&15)<<3;
	return (FILTER*)f;
    } else if(type == FILTERTYPE_GLOW) {
	FILTER_GLOW* f = (FILTER_GLOW*)rfx_calloc(sizeof(FILTER_GLOW));
	f->type = type;
	swf_GetRGBA(tag, &f->rgba);
	f->blurx = swf_GetFixed(tag);
	f->blury = swf_GetFixed(tag);
	f->strength = swf_GetFixed8(tag);
	U8 flags = swf_GetU8(tag);
	f->passes = flags&31;
	f->innerglow = (flags>>7)&1;
	f->knockout = (flags>>6)&1;
	f->composite = (flags>>5)&1;
	return (FILTER*)f;
    } else if(type == FILTERTYPE_GRADIENTGLOW) {
示例#2
0
文件: swftext.c 项目: lieff/lvg
int swf_FontExtract_DefineFontAlignZones(int id, SWFFONT *font, TAG *tag)
{
    uint16_t fid;
    swf_SetTagPos(tag, 0);
    fid = swf_GetU16(tag);

    if (fid == id)
    {
        font->alignzone_flags = swf_GetU8(tag);
        font->alignzones = calloc(1, sizeof(ALIGNZONE)*font->numchars);
        int i = 0;
        while (tag->pos < tag->len)
        {
            if (i >= font->numchars)
                break;
            int nr = swf_GetU8(tag); // should be 2
            if (nr != 1 && nr != 2)
            {
#ifdef _DEBUG
                printf("rfxswf: Can't parse alignzone tags with %d zones", nr);
#endif
                break;
            }
            uint16_t x = swf_GetU16(tag);
            uint16_t y = swf_GetU16(tag);
            uint16_t dx = (nr == 2) ? swf_GetU16(tag) : 0xffff;
            uint16_t dy = (nr == 2) ? swf_GetU16(tag) : 0xffff;
            uint8_t xy = swf_GetU8(tag);

#ifdef _DEBUG
            if ((!(xy & 1) && (x != 0 || (dx != 0 && dx != 0xffff))) ||
                (!(xy & 2) && (y != 0 || (dy != 0 && dy != 0xffff))))
            {
                printf("Warning: weird combination of alignzone bits and values (%d x:%04x-%04x y:%04x-%04x)\n", xy, x, dx, y, dy);
            }
#endif
            if (!(xy & 1))
            {
                x  = 0xffff;
                dx = 0xffff;
            } else if (!(xy & 2))
            {
                y  = 0xffff;
                dy = 0xffff;
            }
            font->alignzones[i].x  = x;
            font->alignzones[i].y  = y;
            font->alignzones[i].dx = dx;
            font->alignzones[i].dy = dy;
            i++;
        }
    }
    return id;
}
示例#3
0
void changedepth(TAG*tag, int add)
{
    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);
    if(tag->id == ST_PLACEOBJECT2) {
	SWFPLACEOBJECT obj;
	U8 flags;
	swf_SetTagPos(tag, 0);
	flags = swf_GetU8(tag);
	if(flags&2) swf_GetU16(tag); //id
	if(flags&4) swf_GetMatrix(tag, 0);
	if(flags&8) swf_GetCXForm(tag, 0,1);
	if(flags&16) swf_GetU16(tag); //ratio
	if(flags&64) {
	    swf_ResetReadBits(tag);
	    printf("%d->%d\n", GET16(&tag->data[tag->pos]),
		               GET16(&tag->data[tag->pos])+add);
	    PUT16(&tag->data[tag->pos],GET16(&tag->data[tag->pos])+add);
	}
	msg("<warning> Depth relocation not fully working yet with clipdepths", tag->id);
    }
}
示例#4
0
ActionTAG* swf_ActionGet(TAG*tag) 
{
    U8 op = 1;
    int length;
    ActionTAG tmp;
    ActionTAG*action = &tmp;
    U8*data;
    while(op)
    {
	action->next = (ActionTAG*)rfx_calloc(sizeof(ActionTAG));
	action->next->prev = action;
	action->next->next = 0;
	action->next->parent = tmp.next;
	action = action->next;

	op = swf_GetU8(tag);
	if(op<0x80)
	    length = 0;
	else
	    length = swf_GetU16(tag);

	if(length) {
	    data = (U8*)rfx_alloc(length);
	    swf_GetBlock(tag, data, length);
	} else {
	  data = 0;
	}
	action->op = op;
	action->len = length;
	action->data = data;
    }
    return tmp.next;
}
示例#5
0
void write_changepos(TAG*output, TAG*tag, int movex, int movey, float scalex, float scaley, int scalepos)
{
    if(movex || movey || scalex != 1.0 || scaley != 1.0)
    {
	switch(tag->id)
	{
	    case ST_PLACEOBJECT2: {
		MATRIX m;
		U8 flags;
		swf_GetMatrix(0, &m);
		tag->pos = 0;
		tag->readBit = 0;

		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
		}
		// flags & 4
		if(flags&4) {
		    swf_GetMatrix(tag, &m);
		} else {
		    swf_GetMatrix(0, &m);
		}
		matrix_adjust(&m, movex, movey, scalex, scaley, scalepos);
		swf_SetMatrix(output, &m);

		if (tag->readBit)  { tag->pos++; tag->readBit = 0; } //swf_ResetReadBits(tag);

		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, movex, movey, scalex, scaley, scalepos);
		swf_SetMatrix(output, &m);
		
		if (tag->readBit)  { tag->pos++; tag->readBit = 0; } //swf_ResetReadBits(tag);

		swf_SetBlock(output, &tag->data[tag->pos], tag->len - tag->pos);
		break;
	    }
	    default:
	    swf_SetBlock(output, tag->data, tag->len);
	}
    } 
    else 
    {
	    swf_SetBlock(output, tag->data, tag->len);
    }
}
示例#6
0
code_t*code_parse(TAG*tag, int len, abc_file_t*file, pool_t*pool, codelookup_t**codelookup)
{
    code_t*head=0;
    code_t*code=0;
    int start=tag->pos;
    int end=tag->pos+len;
    //printf("-->\n");fflush(stdout);

    code_t**bytepos = rfx_calloc(sizeof(code_t*)*len);
        
    while(tag->pos<end) {
        int codepos = tag->pos-start;
        U8 opcode = swf_GetU8(tag);
        opcode_t*op = opcode_get(opcode);
	if(!op) {
	    fprintf(stderr, "Can't parse opcode %02x\n", opcode);
	    continue;
        }
        //printf("%s\n", op->name);fflush(stdout);
        NEW(code_t,c);
        c->pos = codepos;

        bytepos[codepos] = c;

        if(!head) {
            head = code = c;
        } else {
            code->next = c;
            c->prev = code;
            code = c;
        }

        c->opcode = opcode;

        char*p = op->params;
        int pos = 0;
        while(*p) {
            void*data = 0;
            if(*p == 'n') { // number
                data = (void*)(ptroff_t)swf_GetU30(tag);
            } else if(*p == '2') { //multiname
                data = multiname_clone(pool_lookup_multiname(pool, swf_GetU30(tag)));
            } else if(*p == 'N') { //namespace
                data = namespace_clone(pool_lookup_namespace(pool, swf_GetU30(tag)));
            } else if(*p == 'U') { //uint
                data = (void*)(ptroff_t)pool_lookup_uint(pool, swf_GetU30(tag));
            } else if(*p == 'I') { //int
                data = (void*)(ptroff_t)pool_lookup_int(pool, swf_GetU30(tag));
            } else if(*p == 'f') { //int
                double*fp = malloc(sizeof(double));
                *fp = pool_lookup_float(pool, swf_GetU30(tag));
                data = fp;
            } else if(*p == 'm') { //method
                data = array_getvalue(file->methods, swf_GetU30(tag));
            } else if(*p == 'c') { //classinfo
                data = array_getvalue(file->classes, swf_GetU30(tag));
            } else if(*p == 'i') {
                data = array_getvalue(file->method_bodies, swf_GetU30(tag));
            } else if(*p == 'u') { // generic integer
                data = (void*)(ptroff_t)swf_GetU30(tag);
            } else if(*p == 'r') { // local register
                data = (void*)(ptroff_t)swf_GetU30(tag);
            } else if(*p == 'b') { // byte
                data = (void*)(ptroff_t)swf_GetU8(tag);
            } else if(*p == 'j') { // jump
                int j = swf_GetS24(tag);
                data = (void*)(ptroff_t)j;
            } else if(*p == 's') { // string
                string_t s = pool_lookup_string2(pool, swf_GetU30(tag));
                data = string_dup3(&s);
            } else if(*p == 'D') { // debug
                /*type, usually 1*/
                U8 type = swf_GetU8(tag);
                if(type!=1) 
                    fprintf(stderr, "Unknown debug type: %02x\n", type);
                /*register name*/
                code->data[0] = strdup((char*)pool_lookup_string(pool, swf_GetU30(tag)));
                /*register index*/
                code->data[1] = (void*)(ptroff_t)swf_GetU8(tag);
                /*unused*/
                swf_GetU30(tag);
            } else if(*p == 'S') { // switch statement
                lookupswitch_t*l = malloc(sizeof(lookupswitch_t));
                l->def = (code_t*)(ptroff_t)swf_GetS24(tag);
                l->targets = list_new();
                int num = swf_GetU30(tag)+1;
                int t;
                for(t=0;t<num;t++) 
                    list_append(l->targets, (code_t*)(ptroff_t)swf_GetS24(tag));
                data = l;
            } else {
                printf("Can't parse opcode param type \"%c\" (for op %02x %s).\n", *p, code->opcode, op->name);
                return 0;
            }
            if(data)
                code->data[pos++] = data;
            p++;
        }
    }

//#define DEBUG_BYTES
#ifdef DEBUG_BYTES
    int t;
    for(t=0;t<len;t++) {
        code_t*c = bytepos[t];
        if(c) {
            opcode_t*op = opcode_get(c->opcode);
            if(op->flags & (OP_JUMP|OP_BRANCH)) {
                printf("%50d) %02x %s %d\n", t, tag->data[start+t], op->name, c->data[0]);
            } else {
                printf("%50d) %02x %s\n", t, tag->data[start+t], op->name);
            }
        } else {
            printf("%50d) %02x\n", t, tag->data[start+t]);
        }
    }
    //printf("%05d) %02x\n", t, tag->data[start+t]);
#endif

    code_t*c = head;
    while(c) {
        opcode_t*op = opcode_get(c->opcode);
        if(op->flags & (OP_JUMP|OP_BRANCH)) {
            int j = ((int)(ptroff_t)c->data[0]);
            c->branch = pos2code(bytepos,c,j+4,len);
        } else if(op->flags & (OP_LOOKUPSWITCH)) {
            lookupswitch_t*l = (lookupswitch_t*)c->data[0];
            int offset = 0;
            l->def = pos2code(bytepos,c,(ptroff_t)l->def+offset,len);
            code_list_t*t=l->targets;
            while(t) {
                t->code = pos2code(bytepos,c,(ptroff_t)t->code+offset,len);
                t = t->next;
            }
        }
        c = c->next;
    } 

    if(codelookup) {
        (*codelookup) = malloc(sizeof(codelookup_t));
        (*codelookup)->bytepos = bytepos;
        (*codelookup)->len = len;
    } else {
        free(bytepos);
    }

    return head;
}
示例#7
0
文件: swftext.c 项目: lieff/lvg
int swf_FontExtract_DefineFontInfo(int id, SWFFONT *f, TAG *t)
{
    uint16_t fid;
    uint16_t maxcode;
    uint8_t flags;
    swf_SetTagPos(t, 0);

    fid = swf_GetU16(t);
    if (fid == id)
    {
        uint8_t l = swf_GetU8(t);
        int i;

        if (f->version > 1)
        {
            /* Especially with Flash MX, DefineFont2 may have FontInfo fields,
               too. However, they only add little information to what's already
               inside the DefineFont2 tag */
            return id;
        }

        if (f->name)
            free(f->name);

        f->name = (uint8_t *) malloc(l + 1);
        swf_GetBlock(t, f->name, l);
        f->name[l] = 0;

        flags = swf_GetU8(t);
        if (flags & 2)
            f->style |= FONT_STYLE_BOLD;
        if (flags & 4)
            f->style |= FONT_STYLE_ITALIC;
        if (flags & 8)
            f->encoding |= FONT_ENCODING_ANSI;
        if (flags & 16)
            f->encoding |= FONT_ENCODING_SHIFTJIS;
        if (flags & 32)
            f->encoding |= FONT_ENCODING_UNICODE;

        if (t->id == ST_DEFINEFONTINFO2)
        {
            f->language = swf_GetU8(t);
        }

        f->glyph2ascii = (uint16_t *) malloc(sizeof(uint16_t) * f->numchars);
        maxcode = 0;
        for (i = 0; i < f->numchars; i++)
        {
            f->glyph2ascii[i] = ((flags & FF_WIDECODES) ? swf_GetU16(t) : swf_GetU8(t));
            if (f->glyph2ascii[i] > maxcode)
                maxcode = f->glyph2ascii[i];
        }
        maxcode++;
        if (maxcode < 256)
            maxcode = 256;
        f->maxascii = maxcode;
        f->ascii2glyph = (int *)malloc(sizeof(int) * maxcode);
        memset(f->ascii2glyph, -1, sizeof(int) * maxcode);

        for (i = 0; i < f->numchars; i++)
            f->ascii2glyph[f->glyph2ascii[i]] = i;
    }
    return id;
}
示例#8
0
文件: swftext.c 项目: lieff/lvg
int swf_FontExtract_DefineFont2(int id, SWFFONT *font, TAG *tag)
{
    int t, glyphcount;
    int maxcode;
    int fid;
    uint32_t offset_start;
    uint32_t *offset;
    uint8_t flags1, /*langcode, */namelen;
    swf_SetTagPos(tag, 0);
    font->version = tag->id == ST_DEFINEFONT3 ? 3 : 2;
    fid = swf_GetU16(tag);
    if (id && id != fid)
        return id;
    font->id = fid;
    flags1 = swf_GetU8(tag);
    /*langcode = */swf_GetU8(tag);	//reserved flags

    if (flags1 & 1)
        font->style |= FONT_STYLE_BOLD;
    if (flags1 & 2)
        font->style |= FONT_STYLE_ITALIC;
    if (flags1 & 16)
        font->encoding |= FONT_ENCODING_ANSI;
    if (flags1 & 32)
        font->encoding |= FONT_ENCODING_UNICODE;
    if (flags1 & 64)
        font->encoding |= FONT_ENCODING_SHIFTJIS;

    namelen = swf_GetU8(tag);
    font->name = (uint8_t *) malloc(namelen + 1);
    font->name[namelen] = 0;
    swf_GetBlock(tag, font->name, namelen);
    glyphcount = swf_GetU16(tag);
    font->numchars = glyphcount;

    font->glyph = (SWFGLYPH *) calloc(1, sizeof(SWFGLYPH) * glyphcount);
    font->glyph2ascii = (uint16_t *) calloc(1, sizeof(uint16_t) * glyphcount);

    offset = (uint32_t*)calloc(1, sizeof(uint32_t)*(glyphcount + 1));
    offset_start = tag->pos;

    if (flags1 & 8)
    {   // wide offsets
        for (t = 0; t < glyphcount; t++)
            offset[t] = swf_GetU32(tag);	//offset[t]

        if (glyphcount)		/* this _if_ is not in the specs */
            offset[glyphcount] = swf_GetU32(tag);	// fontcodeoffset
        else
            offset[glyphcount] = tag->pos;
    } else
    {
        for (t = 0; t < glyphcount; t++)
            offset[t] = swf_GetU16(tag);	//offset[t]

        if (glyphcount)		/* this _if_ is not in the specs */
            offset[glyphcount] = swf_GetU16(tag);	// fontcodeoffset
        else
            offset[glyphcount] = tag->pos;
    }
    for (t = 0; t < glyphcount; t++)
    {
        swf_SetTagPos(tag, offset[t] + offset_start);
        swf_GetSimpleShape(tag, &(font->glyph[t].shape));
    }

    if (glyphcount)
        swf_SetTagPos(tag, offset[glyphcount] + offset_start);

    free(offset);

    maxcode = 0;
    for (t = 0; t < glyphcount; t++)
    {
        int code;
        if (flags1 & 4)		// wide codes (always on for definefont3)
            code = swf_GetU16(tag);
        else
            code = swf_GetU8(tag);
        font->glyph2ascii[t] = code;
        if (code > maxcode)
            maxcode = code;
    }
    maxcode++;
    if (maxcode < 256)
        maxcode = 256;
    font->maxascii = maxcode;
    font->ascii2glyph = (int *) malloc(sizeof(int) * maxcode);
    memset(font->ascii2glyph, -1, sizeof(int) * maxcode);
    for (t = 0; t < glyphcount; t++)
    {
        font->ascii2glyph[font->glyph2ascii[t]] = t;
    }

    if (flags1 & 128)
    {   // has layout
        uint16_t kerningcount;
        font->layout = (SWFLAYOUT *) malloc(sizeof(SWFLAYOUT));
        font->layout->ascent  = swf_GetU16(tag);
        font->layout->descent = swf_GetU16(tag);
        font->layout->leading = swf_GetU16(tag);
        for (t = 0; t < glyphcount; t++)
        {
            int16_t advance = swf_GetS16(tag);
            font->glyph[t].advance = advance;
        }
        font->layout->bounds = (SRECT*)malloc(glyphcount * sizeof(SRECT));
        for (t = 0; t < glyphcount; t++)
        {
            swf_ResetReadBits(tag);
            swf_GetRect(tag, &font->layout->bounds[t]);
            SRECT b = font->layout->bounds[t];
            if ((b.xmin | b.xmax | b.ymin | b.ymax) == 0)
            {
                // recalculate bounding box
                SHAPE2 *shape2 = swf_ShapeToShape2(font->glyph[t].shape);
                font->layout->bounds[t] = swf_GetShapeBoundingBox(shape2);
                swf_Shape2Free(shape2); free(shape2);
            }
        }

        kerningcount = swf_GetU16(tag);
        font->layout->kerningcount = kerningcount;

        font->layout->kerning = (SWFKERNING *) malloc(sizeof(SWFKERNING) * kerningcount);
        if (kerningcount)
        {
            font->layout->kerning = (SWFKERNING*)malloc(sizeof(*font->layout->kerning) * kerningcount);
            for (t = 0; t < kerningcount; t++)
            {
                if (flags1 & 4)
                {	// wide codes
                    font->layout->kerning[t].char1 = swf_GetU16(tag);
                    font->layout->kerning[t].char2 = swf_GetU16(tag);
                } else
                {
                    font->layout->kerning[t].char1 = swf_GetU8(tag);
                    font->layout->kerning[t].char2 = swf_GetU8(tag);
                }
                font->layout->kerning[t].adjustment = swf_GetS16(tag);
            }
        }
    }
    return font->id;
}