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 U16 id = GET16(idptr);
23 logf("<error> Trying to map id never encountered before: id=%d", id);
26 logf("<debug> mapping %d to %d", id, slaveids[id]);
27 PUT16(idptr, slaveids[id]);
31 void mapstyles(struct reader_t*reader, int num, void(*callback)(void*))
35 reader_resetbits(reader);
36 count = reader_readu8(reader);
37 if(count == 0xff && num>1) // defineshape2,3 only
38 count = reader_readu16(reader);
40 // printf("%d fillstyles\n", count);
45 pos=reader_getinputpos(reader);
46 // printf("%02x %02x %02x %02x %02x %02x %02x %02x\n",
47 // pos[0],pos[1],pos[2],pos[3],pos[4],pos[5],pos[6],pos[7]);
48 reader_resetbits(reader);
49 type = reader_readu8(reader); //type
50 // printf("fillstyle %d is type 0x%02x\n", t, type);
52 // printf("solid fill\n");
58 else if(type == 0x10 || type == 0x12)
60 // printf("gradient fill\n");
61 reader_resetbits(reader);
63 reader_resetbits(reader);
64 readGRADIENT(reader, num);
66 else if(type == 0x40 || type == 0x41)
68 reader_resetbits(reader);
70 // printf("bitmap fill:%04x\n", *(u16*)getinputpos());
71 if(GET16(reader_getinputpos(reader)) != 65535)
72 (callback)(reader_getinputpos(reader));
74 reader_readu16(reader);
75 reader_resetbits(reader);
79 logf("<error> Unknown fillstyle:0x%02x\n",type);
82 reader_resetbits(reader);
83 count = reader_readu8(reader); // line style array
84 // printf("%d linestyles\n", count);
86 count = reader_readu16(reader);
89 reader_readu16(reader);
97 // take a memory region which contains a tag, and
98 // map the ids inside this tag to new values
99 void map_ids_mem(u8*mem, int length, void(*callback)(void*))
102 struct swf_tag newtag_instance;
103 struct swf_tag*newtag = &newtag_instance;
104 struct reader_t reader;
105 reader_init (&reader, mem, length);
106 swf_read_tag(&reader, newtag);
110 case TAGID_DEFINEBUTTONCXFORM: {
112 struct reader_t reader;
113 callback(&newtag->data[0]); //button id
114 reader_init (&reader, newtag->data, newtag->length);
117 callback(&newtag->data[0]);
118 reader_readu16(&reader); //sound id
119 flags = reader_readu8(&reader);
121 reader_readu32(&reader); // in point
123 reader_readu32(&reader); // out points
125 reader_readu16(&reader); // loop count
128 int npoints = reader_readu8(&reader);
130 for(s=0;s<npoints;s++)
132 reader_readu32(&reader);
133 reader_readu16(&reader);
134 reader_readu16(&reader);
139 case TAGID_DEFINEBUTTONSOUND:
140 callback(&newtag->data[0]); //button id
142 case TAGID_PLACEOBJECT:
143 callback(&newtag->data[0]);
145 case TAGID_PLACEOBJECT2:
146 // only if placeflaghascharacter
147 if(!(newtag->data[0]&2))
149 callback(&newtag->data[3]);
151 case TAGID_REMOVEOBJECT:
152 callback(&newtag->data[0]);
154 case TAGID_STARTSOUND:
155 callback(&newtag->data[0]);
157 case TAGID_DEFINESPRITE: {
158 u8*mem = &newtag->data[4];
159 int len = newtag->length-4;
164 struct swf_tag sprtag;
165 struct reader_t reader;
167 reader_init (&reader, mem, len);
168 swf_read_tag (&reader, &sprtag);
170 mem = reader_getinputpos(&reader);
171 len = reader_getinputlength(&reader);
173 if(sprtag.id == TAGID_END)
176 map_ids_mem (fmem,flen,callback);
180 case TAGID_DEFINEBUTTON2: // has some font ids in the button records
183 case TAGID_DEFINEBUTTON: {
184 struct reader_t reader;
185 reader_init (&reader, newtag->data, newtag->length);
186 reader_readu16(&reader); //button id
190 reader_readu8(&reader); //flag
191 offset = reader_readu16(&reader); //offset
196 if(!reader_readu8(&reader)) //flags
198 charid = GET16(reader_getinputpos(&reader));
199 callback(reader_getinputpos(&reader));
200 reader_readu16(&reader); //char
201 reader_readu16(&reader); //layer
202 reader_resetbits(&reader);
205 reader_resetbits(&reader);
206 readCXFORM(&reader, 1);
212 case TAGID_DEFINEEDITTEXT: {
214 struct reader_t reader;
215 reader_init (&reader, newtag->data, newtag->length);
216 reader_readu16(&reader); //id
217 readRECT(&reader); //bounding box
218 reader_resetbits(&reader);
219 flags1 = reader_readu8(&reader);
220 flags2 = reader_readu8(&reader);
222 callback(reader_getinputpos(&reader));
225 case TAGID_DEFINETEXT2:
227 case TAGID_DEFINETEXT: {
228 int glyphbits, advancebits;
230 struct reader_t reader;
231 reader_init (&reader, newtag->data, newtag->length);
232 id = reader_readu16(&reader); //id
233 readRECT(&reader); //bounding box
234 reader_resetbits(&reader);
235 readMATRIX(&reader); //matrix
236 reader_resetbits(&reader);
237 glyphbits = reader_readu8(&reader); //glyphbits
238 advancebits = reader_readu8(&reader); //advancebits
241 reader_resetbits(&reader);
242 flags = reader_getbits(&reader, 8);
244 if(flags & 128) // text style record
246 reader_resetbits(&reader);
247 if(flags & 8) { // hasfont
248 callback(reader_getinputpos(&reader));
249 id = reader_readu16(&reader);
251 if(flags & 4) { // hascolor
252 if(num==1) readRGB(&reader);
253 else readRGBA(&reader);
255 if(flags & 2) { //has x offset
256 reader_resetbits(&reader);
257 reader_readu16(&reader);
259 if(flags & 1) { //has y offset
260 reader_resetbits(&reader);
261 reader_readu16(&reader);
263 if(flags & 8) { //has height
264 reader_resetbits(&reader);
265 reader_readu16(&reader);
267 } else { // glyph record
269 reader_resetbits(&reader);
270 for(t=0;t<flags;t++) {
271 reader_getbits(&reader, glyphbits);
272 reader_getbits(&reader, advancebits);
278 case TAGID_DEFINEFONTINFO:
279 callback(&newtag->data[0]);
282 case TAGID_DEFINESHAPE3: // these thingies might have bitmap ids in their fillstyles
284 case TAGID_DEFINESHAPE2:
286 case TAGID_DEFINESHAPE: {
290 struct reader_t reader;
291 //printf("defineshape%d\n", num);
292 reader_init (&reader, newtag->data, newtag->length);
293 reader_readu16(&reader); // id;
294 r = readRECT(&reader); // bounds
295 // printf("%d shape bounds: %d %d %d %d\n",newtag->id,r.x1,r.y1,r.x2,r.y2);
297 mapstyles(&reader, num, callback);
298 fillbits = reader_getbits(&reader, 4);
299 linebits = reader_getbits(&reader, 4);
300 reader_resetbits(&reader);
301 //printf("%d %d\n", fillbits, linebits);
304 /*printf("data: %02x %02x >%02x< %02x %02x\n",
305 ((u8*)getinputpos())[-2],
306 ((u8*)getinputpos())[-1],
307 ((u8*)getinputpos())[0],
308 ((u8*)getinputpos())[1],
309 ((u8*)getinputpos())[2]);*/
310 flags = reader_getbits(&reader, 1);
311 if(!flags) { //style change
312 flags = reader_getbits(&reader, 5);
313 //printf("style flags:%02x\n",flags);
317 int n = reader_getbits(&reader, 5);
318 //printf("n:%d\n",n);
319 reader_getbits(&reader, n); //x
320 reader_getbits(&reader, n); //y
322 if(flags&2) { //fill0
323 reader_getbits(&reader, fillbits);
325 if(flags&4) { //fill1
326 reader_getbits(&reader, fillbits);
328 if(flags&8) { //linestyle
329 reader_getbits(&reader, linebits);
332 mapstyles(&reader, num, callback);
333 fillbits = reader_getbits(&reader, 4);
334 linebits = reader_getbits(&reader, 4);
337 flags = reader_getbits(&reader, 1);
338 //printf("edge:%d\n", flags);
339 if(flags) { //straight edge
340 int n = reader_getbits(&reader, 4) + 2;
341 if(reader_getbits(&reader, 1)) { //line flag
342 reader_getbits(&reader, n); //delta x
343 reader_getbits(&reader, n); //delta y
345 int v=reader_getbits(&reader, 1);
346 reader_getbits(&reader, n); //vert/horz
348 } else { //curved edge
349 int n = reader_getbits(&reader, 4) + 2;
350 reader_getbits(&reader, n);
351 reader_getbits(&reader, n);
352 reader_getbits(&reader, n);
353 reader_getbits(&reader, n);
366 static int get_free_id()
369 for (t=1;t<65536;t++)
380 static struct swf_tag* map_ids(struct swf_tag*tag)
382 map_ids_mem(tag->fulldata, tag->fulllength, maponeid);
386 void swf_relocate (u8*data, int length, int*_bitmap)
390 read_swf(&file, data, length);
391 memset(slaveids, -1, sizeof(slaveids));
394 while(file.tags[pos].id != 0) {
395 struct swf_tag*tag = &file.tags[pos];
397 logf("<debug> relocator: processing tag %02x", tag->id);
398 map_ids(&file.tags[pos]);
400 if(is_defining_tag(tag->id))
405 id = getidfromtag(tag); //own id
407 if(bitmap[id] < 0) { //free
411 newid = get_free_id(id);
414 slaveids[id] = newid;
416 logf("<debug> relocator: id %d mapped to %d",id, newid);
418 setidintag(tag, newid);
420 logf("<debug> [reloc] write tag %02x (%d bytes in body)",
421 tag->id, tag->length);