2 Implements swf_relocate(), which changes the id range of a swf file in
5 Part of the swftools package.
7 Copyright (c) 2001 Matthias Kramm <kramm@quiss.org>
9 This file is distributed under the GPL, see file COPYING for details */
13 static struct swffile file;
17 void maponeid(void*idpos)
19 u16*idptr = (u16*)idpos;
20 if(slaveids[*idptr]<0) {
21 logf("<error> Trying to map id never encountered before: id=%d", *idptr);
24 logf("<debug> mapping %d to %d", *idptr, slaveids[*idptr]);
25 *idptr = slaveids[*idptr];
29 void mapstyles(int num, void(*callback)(void*))
35 if(count == 0xff && num>1) // defineshape2,3 only
38 // printf("%d fillstyles\n", count);
44 // printf("%02x %02x %02x %02x %02x %02x %02x %02x\n",
45 // pos[0],pos[1],pos[2],pos[3],pos[4],pos[5],pos[6],pos[7]);
47 type = readu8(); //type
48 // printf("fillstyle %d is type 0x%02x\n", t, type);
50 // printf("solid fill\n");
56 else if(type == 0x10 || type == 0x12)
58 // printf("gradient fill\n");
64 else if(type == 0x40 || type == 0x41)
68 // printf("bitmap fill:%04x\n", *(u16*)getinputpos());
69 if(*(u16*)getinputpos() != 65535)
70 (callback)(getinputpos());
77 logf("<error> Unknown fillstyle:0x%02x\n",type);
81 count = readu8(); // line style array
82 // printf("%d linestyles\n", count);
95 // take a memory region which contains a tag, and
96 // map the ids inside this tag to new values
97 void map_ids_mem(u8*mem, int length, void(*callback)(void*))
100 struct swf_tag newtag_instance;
101 struct swf_tag*newtag = &newtag_instance;
102 reader_init (mem, length);
103 swf_read_tag(newtag);
107 case TAGID_DEFINEBUTTONCXFORM: {
109 callback(&newtag->data[0]); //button id
110 reader_init (newtag->data, newtag->length);
113 callback(&newtag->data[0]);
114 readu16(); //sound id
117 readu32(); // in point
119 readu32(); // out points
121 readu16(); // loop count
124 int npoints = readu8();
126 for(s=0;s<npoints;s++)
135 case TAGID_DEFINEBUTTONSOUND:
136 callback(&newtag->data[0]); //button id
138 case TAGID_PLACEOBJECT:
139 callback(&newtag->data[0]);
141 case TAGID_PLACEOBJECT2:
142 // only if placeflaghascharacter
143 if(!(newtag->data[0]&2))
145 callback(&newtag->data[3]);
147 case TAGID_REMOVEOBJECT:
148 callback(&newtag->data[0]);
150 case TAGID_STARTSOUND:
151 callback(&newtag->data[0]);
153 case TAGID_DEFINESPRITE: {
154 u8*mem = &newtag->data[4];
155 int len = newtag->length-4;
160 struct swf_tag sprtag;
162 reader_init (mem, len);
163 swf_read_tag (&sprtag);
166 len = getinputlength();
168 if(sprtag.id == TAGID_END)
171 map_ids_mem (fmem,flen,callback);
175 case TAGID_DEFINEBUTTON2: // has some font ids in the button records
178 case TAGID_DEFINEBUTTON:
179 reader_init (newtag->data, newtag->length);
180 readu16(); //button id
185 offset = readu16(); //offset
190 if(!readu8()) //flags
192 charid = *(u16*)getinputpos();
193 callback(getinputpos());
205 case TAGID_DEFINEEDITTEXT: {
207 reader_init (newtag->data, newtag->length);
209 readRECT(); //bounding box
214 callback(getinputpos());
217 case TAGID_DEFINETEXT2:
219 case TAGID_DEFINETEXT: {
220 int glyphbits, advancebits;
222 reader_init (newtag->data, newtag->length);
224 readRECT(); //bounding box
226 readMATRIX(); //matrix
228 glyphbits = readu8(); //glyphbits
229 advancebits = readu8(); //advancebits
235 if(flags & 128) // text style record
238 if(flags & 8) { // hasfont
239 callback(getinputpos());
242 if(flags & 4) { // hascolor
243 if(num==1) readRGB();
246 if(flags & 2) { //has x offset
250 if(flags & 1) { //has y offset
254 if(flags & 8) { //has height
258 } else { // glyph record
261 for(t=0;t<flags;t++) {
263 getbits(advancebits);
269 case TAGID_DEFINEFONTINFO:
270 callback(&newtag->data[0]);
273 case TAGID_DEFINESHAPE3: // these thingies might have bitmap ids in their fillstyles
275 case TAGID_DEFINESHAPE2:
277 case TAGID_DEFINESHAPE: {
281 //printf("defineshape%d\n", num);
282 reader_init (newtag->data, newtag->length);
284 r = readRECT(); // bounds
285 // printf("%d shape bounds: %d %d %d %d\n",newtag->id,r.x1,r.y1,r.x2,r.y2);
287 mapstyles(num, callback);
288 fillbits = getbits(4);
289 linebits = getbits(4);
291 //printf("%d %d\n", fillbits, linebits);
294 /*printf("data: %02x %02x >%02x< %02x %02x\n",
295 ((u8*)getinputpos())[-2],
296 ((u8*)getinputpos())[-1],
297 ((u8*)getinputpos())[0],
298 ((u8*)getinputpos())[1],
299 ((u8*)getinputpos())[2]);*/
301 if(!flags) { //style change
303 //printf("style flags:%02x\n",flags);
308 //printf("n:%d\n",n);
312 if(flags&2) { //fill0
315 if(flags&4) { //fill1
318 if(flags&8) { //linestyle
322 mapstyles(num, callback);
323 fillbits = getbits(4);
324 linebits = getbits(4);
328 //printf("edge:%d\n", flags);
329 if(flags) { //straight edge
330 int n = getbits(4) + 2;
331 if(getbits(1)) { //line flag
332 getbits(n); //delta x
333 getbits(n); //delta y
336 getbits(n); //vert/horz
338 } else { //curved edge
339 int n = getbits(4) + 2;
356 static int get_free_id()
359 for (t=1;t<65536;t++)
370 static struct swf_tag* map_ids(struct swf_tag*tag)
372 map_ids_mem(tag->fulldata, tag->fulllength, maponeid);
376 void swf_relocate (u8*data, int length, int*_bitmap)
380 read_swf(&file, data, length);
381 memset(slaveids, -1, sizeof(slaveids));
384 while(file.tags[pos].id != 0) {
385 struct swf_tag*tag = &file.tags[pos];
387 logf("<debug> relocator: processing tag %02x", tag->id);
388 map_ids(&file.tags[pos]);
390 if(is_defining_tag(tag->id))
395 id = getidfromtag(tag); //own id
397 if(bitmap[id] < 0) { //free
401 newid = get_free_id(id);
404 slaveids[id] = newid;
406 logf("<debug> relocator: id %d mapped to %d",id, newid);
408 setidintag(tag, newid);
410 logf("<debug> [reloc] write tag %02x (%d bytes in body)",
411 tag->id, tag->length);