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 */
12 #include "../lib/rfxswf.h"
14 static struct swffile file;
18 void maponeid(void*idpos)
20 u16*idptr = (u16*)idpos;
21 if(slaveids[SWAP16(*idptr)]<0) {
22 logf("<error> Trying to map id never encountered before: id=%d", *idptr);
25 logf("<debug> mapping %d to %d", SWAP16(*idptr), slaveids[*idptr]);
26 *idptr = SWAP16(slaveids[*idptr]);
30 void mapstyles(struct reader_t*reader, int num, void(*callback)(void*))
34 reader_resetbits(reader);
35 count = reader_readu8(reader);
36 if(count == 0xff && num>1) // defineshape2,3 only
37 count = reader_readu16(reader);
39 // printf("%d fillstyles\n", count);
44 pos=reader_getinputpos(reader);
45 // printf("%02x %02x %02x %02x %02x %02x %02x %02x\n",
46 // pos[0],pos[1],pos[2],pos[3],pos[4],pos[5],pos[6],pos[7]);
47 reader_resetbits(reader);
48 type = reader_readu8(reader); //type
49 // printf("fillstyle %d is type 0x%02x\n", t, type);
51 // printf("solid fill\n");
57 else if(type == 0x10 || type == 0x12)
59 // printf("gradient fill\n");
60 reader_resetbits(reader);
62 reader_resetbits(reader);
63 readGRADIENT(reader, num);
65 else if(type == 0x40 || type == 0x41)
67 reader_resetbits(reader);
69 // printf("bitmap fill:%04x\n", *(u16*)getinputpos());
70 if(*(u16*)reader_getinputpos(reader) != 65535)
71 (callback)(reader_getinputpos(reader));
73 reader_readu16(reader);
74 reader_resetbits(reader);
78 logf("<error> Unknown fillstyle:0x%02x\n",type);
81 reader_resetbits(reader);
82 count = reader_readu8(reader); // line style array
83 // printf("%d linestyles\n", count);
85 count = reader_readu16(reader);
88 reader_readu16(reader);
96 // take a memory region which contains a tag, and
97 // map the ids inside this tag to new values
98 void map_ids_mem(u8*mem, int length, void(*callback)(void*))
101 struct swf_tag newtag_instance;
102 struct swf_tag*newtag = &newtag_instance;
103 struct reader_t reader;
104 reader_init (&reader, mem, length);
105 swf_read_tag(&reader, newtag);
109 case TAGID_DEFINEBUTTONCXFORM: {
111 struct reader_t reader;
112 callback(&newtag->data[0]); //button id
113 reader_init (&reader, newtag->data, newtag->length);
116 callback(&newtag->data[0]);
117 reader_readu16(&reader); //sound id
118 flags = reader_readu8(&reader);
120 reader_readu32(&reader); // in point
122 reader_readu32(&reader); // out points
124 reader_readu16(&reader); // loop count
127 int npoints = reader_readu8(&reader);
129 for(s=0;s<npoints;s++)
131 reader_readu32(&reader);
132 reader_readu16(&reader);
133 reader_readu16(&reader);
138 case TAGID_DEFINEBUTTONSOUND:
139 callback(&newtag->data[0]); //button id
141 case TAGID_PLACEOBJECT:
142 callback(&newtag->data[0]);
144 case TAGID_PLACEOBJECT2:
145 // only if placeflaghascharacter
146 if(!(newtag->data[0]&2))
148 callback(&newtag->data[3]);
150 case TAGID_REMOVEOBJECT:
151 callback(&newtag->data[0]);
153 case TAGID_STARTSOUND:
154 callback(&newtag->data[0]);
156 case TAGID_DEFINESPRITE: {
157 u8*mem = &newtag->data[4];
158 int len = newtag->length-4;
163 struct swf_tag sprtag;
164 struct reader_t reader;
166 reader_init (&reader, mem, len);
167 swf_read_tag (&reader, &sprtag);
169 mem = reader_getinputpos(&reader);
170 len = reader_getinputlength(&reader);
172 if(sprtag.id == TAGID_END)
175 map_ids_mem (fmem,flen,callback);
179 case TAGID_DEFINEBUTTON2: // has some font ids in the button records
182 case TAGID_DEFINEBUTTON: {
183 struct reader_t reader;
184 reader_init (&reader, newtag->data, newtag->length);
185 reader_readu16(&reader); //button id
189 reader_readu8(&reader); //flag
190 offset = reader_readu16(&reader); //offset
195 if(!reader_readu8(&reader)) //flags
197 charid = *(u16*)reader_getinputpos(&reader);
198 callback(reader_getinputpos(&reader));
199 reader_readu16(&reader); //char
200 reader_readu16(&reader); //layer
201 reader_resetbits(&reader);
204 reader_resetbits(&reader);
205 readCXFORM(&reader, 1);
211 case TAGID_DEFINEEDITTEXT: {
213 struct reader_t reader;
214 reader_init (&reader, newtag->data, newtag->length);
215 reader_readu16(&reader); //id
216 readRECT(&reader); //bounding box
217 reader_resetbits(&reader);
218 flags1 = reader_readu8(&reader);
219 flags2 = reader_readu8(&reader);
221 callback(reader_getinputpos(&reader));
224 case TAGID_DEFINETEXT2:
226 case TAGID_DEFINETEXT: {
227 int glyphbits, advancebits;
229 struct reader_t reader;
230 reader_init (&reader, newtag->data, newtag->length);
231 id = reader_readu16(&reader); //id
232 readRECT(&reader); //bounding box
233 reader_resetbits(&reader);
234 readMATRIX(&reader); //matrix
235 reader_resetbits(&reader);
236 glyphbits = reader_readu8(&reader); //glyphbits
237 advancebits = reader_readu8(&reader); //advancebits
240 reader_resetbits(&reader);
241 flags = reader_getbits(&reader, 8);
243 if(flags & 128) // text style record
245 reader_resetbits(&reader);
246 if(flags & 8) { // hasfont
247 callback(reader_getinputpos(&reader));
248 id = reader_readu16(&reader);
250 if(flags & 4) { // hascolor
251 if(num==1) readRGB(&reader);
252 else readRGBA(&reader);
254 if(flags & 2) { //has x offset
255 reader_resetbits(&reader);
256 reader_readu16(&reader);
258 if(flags & 1) { //has y offset
259 reader_resetbits(&reader);
260 reader_readu16(&reader);
262 if(flags & 8) { //has height
263 reader_resetbits(&reader);
264 reader_readu16(&reader);
266 } else { // glyph record
268 reader_resetbits(&reader);
269 for(t=0;t<flags;t++) {
270 reader_getbits(&reader, glyphbits);
271 reader_getbits(&reader, advancebits);
277 case TAGID_DEFINEFONTINFO:
278 callback(&newtag->data[0]);
281 case TAGID_DEFINESHAPE3: // these thingies might have bitmap ids in their fillstyles
283 case TAGID_DEFINESHAPE2:
285 case TAGID_DEFINESHAPE: {
289 struct reader_t reader;
290 //printf("defineshape%d\n", num);
291 reader_init (&reader, newtag->data, newtag->length);
292 reader_readu16(&reader); // id;
293 r = readRECT(&reader); // bounds
294 // printf("%d shape bounds: %d %d %d %d\n",newtag->id,r.x1,r.y1,r.x2,r.y2);
296 mapstyles(&reader, num, callback);
297 fillbits = reader_getbits(&reader, 4);
298 linebits = reader_getbits(&reader, 4);
299 reader_resetbits(&reader);
300 //printf("%d %d\n", fillbits, linebits);
303 /*printf("data: %02x %02x >%02x< %02x %02x\n",
304 ((u8*)getinputpos())[-2],
305 ((u8*)getinputpos())[-1],
306 ((u8*)getinputpos())[0],
307 ((u8*)getinputpos())[1],
308 ((u8*)getinputpos())[2]);*/
309 flags = reader_getbits(&reader, 1);
310 if(!flags) { //style change
311 flags = reader_getbits(&reader, 5);
312 //printf("style flags:%02x\n",flags);
316 int n = reader_getbits(&reader, 5);
317 //printf("n:%d\n",n);
318 reader_getbits(&reader, n); //x
319 reader_getbits(&reader, n); //y
321 if(flags&2) { //fill0
322 reader_getbits(&reader, fillbits);
324 if(flags&4) { //fill1
325 reader_getbits(&reader, fillbits);
327 if(flags&8) { //linestyle
328 reader_getbits(&reader, linebits);
331 mapstyles(&reader, num, callback);
332 fillbits = reader_getbits(&reader, 4);
333 linebits = reader_getbits(&reader, 4);
336 flags = reader_getbits(&reader, 1);
337 //printf("edge:%d\n", flags);
338 if(flags) { //straight edge
339 int n = reader_getbits(&reader, 4) + 2;
340 if(reader_getbits(&reader, 1)) { //line flag
341 reader_getbits(&reader, n); //delta x
342 reader_getbits(&reader, n); //delta y
344 int v=reader_getbits(&reader, 1);
345 reader_getbits(&reader, n); //vert/horz
347 } else { //curved edge
348 int n = reader_getbits(&reader, 4) + 2;
349 reader_getbits(&reader, n);
350 reader_getbits(&reader, n);
351 reader_getbits(&reader, n);
352 reader_getbits(&reader, n);
365 static int get_free_id()
368 for (t=1;t<65536;t++)
379 static struct swf_tag* map_ids(struct swf_tag*tag)
381 map_ids_mem(tag->fulldata, tag->fulllength, maponeid);
385 void swf_relocate (u8*data, int length, int*_bitmap)
389 read_swf(&file, data, length);
390 memset(slaveids, -1, sizeof(slaveids));
393 while(file.tags[pos].id != 0) {
394 struct swf_tag*tag = &file.tags[pos];
396 logf("<debug> relocator: processing tag %02x", tag->id);
397 map_ids(&file.tags[pos]);
399 if(is_defining_tag(tag->id))
404 id = getidfromtag(tag); //own id
406 if(bitmap[id] < 0) { //free
410 newid = get_free_id(id);
413 slaveids[id] = newid;
415 logf("<debug> relocator: id %d mapped to %d",id, newid);
417 setidintag(tag, newid);
419 logf("<debug> [reloc] write tag %02x (%d bytes in body)",
420 tag->id, tag->length);