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(struct reader_t*reader, int num, void(*callback)(void*))
33 reader_resetbits(reader);
34 count = reader_readu8(reader);
35 if(count == 0xff && num>1) // defineshape2,3 only
36 count = reader_readu16(reader);
38 // printf("%d fillstyles\n", count);
43 pos=reader_getinputpos(reader);
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]);
46 reader_resetbits(reader);
47 type = reader_readu8(reader); //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");
59 reader_resetbits(reader);
61 reader_resetbits(reader);
62 readGRADIENT(reader, num);
64 else if(type == 0x40 || type == 0x41)
66 reader_resetbits(reader);
68 // printf("bitmap fill:%04x\n", *(u16*)getinputpos());
69 if(*(u16*)reader_getinputpos(reader) != 65535)
70 (callback)(reader_getinputpos(reader));
72 reader_readu16(reader);
73 reader_resetbits(reader);
77 logf("<error> Unknown fillstyle:0x%02x\n",type);
80 reader_resetbits(reader);
81 count = reader_readu8(reader); // line style array
82 // printf("%d linestyles\n", count);
84 count = reader_readu16(reader);
87 reader_readu16(reader);
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 struct reader_t reader;
103 reader_init (&reader, mem, length);
104 swf_read_tag(&reader, newtag);
108 case TAGID_DEFINEBUTTONCXFORM: {
110 struct reader_t reader;
111 callback(&newtag->data[0]); //button id
112 reader_init (&reader, newtag->data, newtag->length);
115 callback(&newtag->data[0]);
116 reader_readu16(&reader); //sound id
117 flags = reader_readu8(&reader);
119 reader_readu32(&reader); // in point
121 reader_readu32(&reader); // out points
123 reader_readu16(&reader); // loop count
126 int npoints = reader_readu8(&reader);
128 for(s=0;s<npoints;s++)
130 reader_readu32(&reader);
131 reader_readu16(&reader);
132 reader_readu16(&reader);
137 case TAGID_DEFINEBUTTONSOUND:
138 callback(&newtag->data[0]); //button id
140 case TAGID_PLACEOBJECT:
141 callback(&newtag->data[0]);
143 case TAGID_PLACEOBJECT2:
144 // only if placeflaghascharacter
145 if(!(newtag->data[0]&2))
147 callback(&newtag->data[3]);
149 case TAGID_REMOVEOBJECT:
150 callback(&newtag->data[0]);
152 case TAGID_STARTSOUND:
153 callback(&newtag->data[0]);
155 case TAGID_DEFINESPRITE: {
156 u8*mem = &newtag->data[4];
157 int len = newtag->length-4;
162 struct swf_tag sprtag;
163 struct reader_t reader;
165 reader_init (&reader, mem, len);
166 swf_read_tag (&reader, &sprtag);
168 mem = reader_getinputpos(&reader);
169 len = reader_getinputlength(&reader);
171 if(sprtag.id == TAGID_END)
174 map_ids_mem (fmem,flen,callback);
178 case TAGID_DEFINEBUTTON2: // has some font ids in the button records
181 case TAGID_DEFINEBUTTON: {
182 struct reader_t reader;
183 reader_init (&reader, newtag->data, newtag->length);
184 reader_readu16(&reader); //button id
188 reader_readu8(&reader); //flag
189 offset = reader_readu16(&reader); //offset
194 if(!reader_readu8(&reader)) //flags
196 charid = *(u16*)reader_getinputpos(&reader);
197 callback(reader_getinputpos(&reader));
198 reader_readu16(&reader); //char
199 reader_readu16(&reader); //layer
200 reader_resetbits(&reader);
203 reader_resetbits(&reader);
204 readCXFORM(&reader, 1);
210 case TAGID_DEFINEEDITTEXT: {
212 struct reader_t reader;
213 reader_init (&reader, newtag->data, newtag->length);
214 reader_readu16(&reader); //id
215 readRECT(&reader); //bounding box
216 reader_resetbits(&reader);
217 flags1 = reader_readu8(&reader);
218 flags2 = reader_readu8(&reader);
220 callback(reader_getinputpos(&reader));
223 case TAGID_DEFINETEXT2:
225 case TAGID_DEFINETEXT: {
226 int glyphbits, advancebits;
228 struct reader_t reader;
229 reader_init (&reader, newtag->data, newtag->length);
230 id = reader_readu16(&reader); //id
231 readRECT(&reader); //bounding box
232 reader_resetbits(&reader);
233 readMATRIX(&reader); //matrix
234 reader_resetbits(&reader);
235 glyphbits = reader_readu8(&reader); //glyphbits
236 advancebits = reader_readu8(&reader); //advancebits
239 reader_resetbits(&reader);
240 flags = reader_getbits(&reader, 8);
242 if(flags & 128) // text style record
244 reader_resetbits(&reader);
245 if(flags & 8) { // hasfont
246 callback(reader_getinputpos(&reader));
247 id = reader_readu16(&reader);
249 if(flags & 4) { // hascolor
250 if(num==1) readRGB(&reader);
251 else readRGBA(&reader);
253 if(flags & 2) { //has x offset
254 reader_resetbits(&reader);
255 reader_readu16(&reader);
257 if(flags & 1) { //has y offset
258 reader_resetbits(&reader);
259 reader_readu16(&reader);
261 if(flags & 8) { //has height
262 reader_resetbits(&reader);
263 reader_readu16(&reader);
265 } else { // glyph record
267 reader_resetbits(&reader);
268 for(t=0;t<flags;t++) {
269 reader_getbits(&reader, glyphbits);
270 reader_getbits(&reader, advancebits);
276 case TAGID_DEFINEFONTINFO:
277 callback(&newtag->data[0]);
280 case TAGID_DEFINESHAPE3: // these thingies might have bitmap ids in their fillstyles
282 case TAGID_DEFINESHAPE2:
284 case TAGID_DEFINESHAPE: {
288 struct reader_t reader;
289 //printf("defineshape%d\n", num);
290 reader_init (&reader, newtag->data, newtag->length);
291 reader_readu16(&reader); // id;
292 r = readRECT(&reader); // bounds
293 // printf("%d shape bounds: %d %d %d %d\n",newtag->id,r.x1,r.y1,r.x2,r.y2);
295 mapstyles(&reader, num, callback);
296 fillbits = reader_getbits(&reader, 4);
297 linebits = reader_getbits(&reader, 4);
298 reader_resetbits(&reader);
299 //printf("%d %d\n", fillbits, linebits);
302 /*printf("data: %02x %02x >%02x< %02x %02x\n",
303 ((u8*)getinputpos())[-2],
304 ((u8*)getinputpos())[-1],
305 ((u8*)getinputpos())[0],
306 ((u8*)getinputpos())[1],
307 ((u8*)getinputpos())[2]);*/
308 flags = reader_getbits(&reader, 1);
309 if(!flags) { //style change
310 flags = reader_getbits(&reader, 5);
311 //printf("style flags:%02x\n",flags);
315 int n = reader_getbits(&reader, 5);
316 //printf("n:%d\n",n);
317 reader_getbits(&reader, n); //x
318 reader_getbits(&reader, n); //y
320 if(flags&2) { //fill0
321 reader_getbits(&reader, fillbits);
323 if(flags&4) { //fill1
324 reader_getbits(&reader, fillbits);
326 if(flags&8) { //linestyle
327 reader_getbits(&reader, linebits);
330 mapstyles(&reader, num, callback);
331 fillbits = reader_getbits(&reader, 4);
332 linebits = reader_getbits(&reader, 4);
335 flags = reader_getbits(&reader, 1);
336 //printf("edge:%d\n", flags);
337 if(flags) { //straight edge
338 int n = reader_getbits(&reader, 4) + 2;
339 if(reader_getbits(&reader, 1)) { //line flag
340 reader_getbits(&reader, n); //delta x
341 reader_getbits(&reader, n); //delta y
343 int v=reader_getbits(&reader, 1);
344 reader_getbits(&reader, n); //vert/horz
346 } else { //curved edge
347 int n = reader_getbits(&reader, 4) + 2;
348 reader_getbits(&reader, n);
349 reader_getbits(&reader, n);
350 reader_getbits(&reader, n);
351 reader_getbits(&reader, n);
364 static int get_free_id()
367 for (t=1;t<65536;t++)
378 static struct swf_tag* map_ids(struct swf_tag*tag)
380 map_ids_mem(tag->fulldata, tag->fulllength, maponeid);
384 void swf_relocate (u8*data, int length, int*_bitmap)
388 read_swf(&file, data, length);
389 memset(slaveids, -1, sizeof(slaveids));
392 while(file.tags[pos].id != 0) {
393 struct swf_tag*tag = &file.tags[pos];
395 logf("<debug> relocator: processing tag %02x", tag->id);
396 map_ids(&file.tags[pos]);
398 if(is_defining_tag(tag->id))
403 id = getidfromtag(tag); //own id
405 if(bitmap[id] < 0) { //free
409 newid = get_free_id(id);
412 slaveids[id] = newid;
414 logf("<debug> relocator: id %d mapped to %d",id, newid);
416 setidintag(tag, newid);
418 logf("<debug> [reloc] write tag %02x (%d bytes in body)",
419 tag->id, tag->length);