1 /****************************************************************************
2 *
3 * Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
4 * Copyright (C) 2005-2006 Stuart R. Anderson <anderson@netsweng.com>
5 * Copyright (C) 2001 Raffaele Sena
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 ****************************************************************************/
22
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <assert.h>
27
28 #include "parser.h"
29
30 int fileOffset = 0;
31
32 int buffer;
33 int bufbits = 0; /* # of bits in buffer */
34
byteAlign()35 void byteAlign()
36 {
37 if(bufbits > 0)
38 {
39 bufbits = 0;
40 buffer = 0;
41 }
42 }
43
readBits(FILE * f,int number)44 int readBits(FILE *f, int number)
45 {
46 int ret = buffer;
47 int tmp_char;
48
49 if(number == bufbits)
50 {
51 bufbits = 0;
52 buffer = 0;
53 return ret;
54 }
55
56 if(number > bufbits)
57 {
58 number -= bufbits;
59
60 while(number>8)
61 {
62 tmp_char = fgetc(f);
63 if (tmp_char == EOF)
64 {
65 // exit here instead of crashing elswhere
66 fprintf(stderr, "truncated file\n");
67 exit(-1);
68 }
69
70 ret <<= 8;
71 ret += tmp_char;
72 ++fileOffset;
73 number -= 8;
74 }
75
76 ++fileOffset;
77 tmp_char = fgetc(f);
78 if (tmp_char == EOF)
79 {
80 // exit here instead of crashing elswhere
81 fprintf(stderr, "truncated file\n");
82 exit(-1);
83 }
84
85 buffer = tmp_char;
86
87 if(number>0)
88 {
89 ret <<= number;
90 bufbits = 8-number;
91 ret += buffer >> (8-number);
92 buffer &= (1<<bufbits)-1;
93 }
94
95 return ret;
96 }
97
98 ret = buffer >> (bufbits-number);
99 bufbits -= number;
100 buffer &= (1<<bufbits)-1;
101
102 return ret;
103 }
104
readSBits(FILE * f,int number)105 int readSBits(FILE *f, int number)
106 {
107 int num = readBits(f, number);
108
109 if(num & (1<<(number-1)))
110 return num - (1<<number);
111 else
112 return num;
113 }
114
readRect(FILE * f,struct Rect * s)115 void readRect(FILE *f, struct Rect *s)
116 {
117 int nBits;
118 byteAlign();
119
120 nBits = readBits(f, 5);
121 s->xMin = readSBits(f, nBits);
122 s->xMax = readSBits(f, nBits);
123 s->yMin = readSBits(f, nBits);
124 s->yMax = readSBits(f, nBits);
125 }
126
readUInt8(FILE * f)127 int readUInt8(FILE *f)
128 {
129 int tmp_char = fgetc(f);
130 // the rest of the code does not handle errors and use EOF as a valid unsigned char value
131 if (tmp_char == EOF)
132 {
133 // exit here instead of crashing elswhere
134 fprintf(stderr, "truncated file\n");
135 exit(-1);
136 }
137
138 bufbits = 0;
139 ++fileOffset;
140 return tmp_char;
141 }
142
readSInt8(FILE * f)143 int readSInt8(FILE *f)
144 {
145 return (signed char)readUInt8(f);
146 }
147
readSInt16(FILE * f)148 int readSInt16(FILE *f)
149 {
150 return readUInt8(f) + readSInt8(f)*256;
151 }
152
readUInt16(FILE * f)153 int readUInt16(FILE *f)
154 {
155 return readUInt8(f) + (readUInt8(f)<<8);
156 }
157
readSInt32(FILE * f)158 long readSInt32(FILE *f)
159 {
160 return (long)readUInt8(f) + (readUInt8(f)<<8) + (readUInt8(f)<<16) + (readUInt8(f)<<24);
161 }
162
readUInt32(FILE * f)163 unsigned long readUInt32(FILE *f)
164 {
165 return (unsigned long)(readUInt8(f) + (readUInt8(f)<<8) + (readUInt8(f)<<16) + (readUInt8(f)<<24));
166 }
167
readDouble(FILE * f)168 double readDouble(FILE *f)
169 {
170 union {
171 char c[8];
172 double d;
173 } data;
174
175 #ifdef SWF_LITTLE_ENDIAN
176 data.c[4] = readUInt8(f);
177 data.c[5] = readUInt8(f);
178 data.c[6] = readUInt8(f);
179 data.c[7] = readUInt8(f);
180 data.c[0] = readUInt8(f);
181 data.c[1] = readUInt8(f);
182 data.c[2] = readUInt8(f);
183 data.c[3] = readUInt8(f);
184 #else
185 data.c[3] = readUInt8(f);
186 data.c[2] = readUInt8(f);
187 data.c[1] = readUInt8(f);
188 data.c[0] = readUInt8(f);
189 data.c[7] = readUInt8(f);
190 data.c[6] = readUInt8(f);
191 data.c[5] = readUInt8(f);
192 data.c[4] = readUInt8(f);
193 #endif
194
195
196 return data.d;
197 }
198
readFloat(FILE * f)199 float readFloat(FILE *f)
200 {
201 union {
202 char c[4];
203 float f;
204 } data;
205
206 #ifdef SWF_LITTLE_ENDIAN
207 data.c[0] = readUInt8(f);
208 data.c[1] = readUInt8(f);
209 data.c[2] = readUInt8(f);
210 data.c[3] = readUInt8(f);
211 #else
212 data.c[3] = readUInt8(f);
213 data.c[2] = readUInt8(f);
214 data.c[1] = readUInt8(f);
215 data.c[0] = readUInt8(f);
216 #endif
217
218 return data.f;
219 }
220
221
readBytes(FILE * f,int size)222 char *readBytes(FILE *f,int size)
223 {
224 int i;
225 char *buf;
226
227 buf = (char *)malloc(sizeof(char)*size);
228
229 for(i=0;i<size;i++)
230 {
231 buf[i]=(char)readUInt8(f);
232 }
233
234 return buf;
235 }
236
readString(FILE * f)237 char *readString(FILE *f)
238 {
239 int len = 0, buflen = 256;
240 char c, *buf, *p;
241
242 buf = (char *)malloc(sizeof(char)*256);
243 p = buf;
244
245 while((c=(char)readUInt8(f)) != '\0')
246 {
247 if(len >= buflen-2)
248 {
249 buf = (char *)realloc(buf, sizeof(char)*(buflen+256));
250 buflen += 256;
251 p = buf+len;
252 }
253
254 switch(c)
255 {
256 case '\n':
257 *(p++) = '\\'; *(p++) = 'n'; ++len; break;
258 case '\t':
259 *(p++) = '\\'; *(p++) = 't'; ++len; break;
260 case '\r':
261 *(p++) = '\\'; *(p++) = 'r'; ++len; break;
262 default:
263 *(p++) = c;
264 }
265
266 ++len;
267 }
268
269 *p = 0;
270
271 return buf;
272 }
273
274 #define ENC_BITSPERBYTE 7
275 #define ENC_BYTEMASK 0x7f
276 #define ENC_U30_VERIFY 0xfc
277 #define ENC_HIGHBIT 0x80
278
hasNextByte(unsigned int b)279 static inline int hasNextByte(unsigned int b)
280 {
281 if(!(b & ENC_HIGHBIT))
282 return 0;
283 return 1;
284 }
285
readEncSInt32(FILE * f)286 signed long readEncSInt32(FILE *f)
287 {
288 signed long result = 0, temp;
289 int shift = 0;
290 do
291 {
292 if(shift > 4 * ENC_BITSPERBYTE)
293 break;
294
295 temp = readUInt8(f);
296 result |= (ENC_BYTEMASK & temp) << shift;
297 shift += ENC_BITSPERBYTE;
298 } while (hasNextByte(temp));
299 return result;
300 }
301
readEncUInt30(FILE * f)302 unsigned long readEncUInt30(FILE *f)
303 {
304 unsigned long result = 0, temp;
305 int shift = 0;
306 do
307 {
308 if(shift > 4 * ENC_BITSPERBYTE)
309 break;
310
311 temp = readUInt8(f);
312 result |= (ENC_BYTEMASK & temp) << shift;
313 shift += ENC_BITSPERBYTE;
314 } while (hasNextByte(temp));
315
316 //if((temp & ENC_U30_VERIFY) && shift > 4 * ENC_BITSPERBYTE)
317 // printf("readEncUInt30: verification error\n");
318
319 return result;
320 }
321
readEncUInt32(FILE * f)322 unsigned long readEncUInt32(FILE *f)
323 {
324 unsigned long result = 0, temp;
325 int shift = 0;
326 do
327 {
328 if(shift > 4 * ENC_BITSPERBYTE)
329 break;
330
331 temp = readUInt8(f);
332 result |= (ENC_BYTEMASK & temp) << shift;
333 shift += ENC_BITSPERBYTE;
334 } while (hasNextByte(temp));
335
336 return result;
337 }
338
readSizedString(FILE * f,int size)339 char *readSizedString(FILE *f,int size)
340 {
341 int len = 0, buflen = 256, i;
342 char c, *buf, *p;
343
344 buf = (char *)malloc(sizeof(char)*buflen);
345 p = buf;
346
347 for(i=0;i<size;i++)
348 {
349 c=(char)readUInt8(f);
350 if(len >= buflen-2)
351 {
352 buf = (char *)realloc(buf, sizeof(char)*(buflen+256));
353 buflen += 256;
354 p = buf+len;
355 }
356
357 switch(c)
358 {
359 case '\n':
360 *(p++) = '\\'; *(p++) = 'n'; ++len; break;
361 case '\t':
362 *(p++) = '\\'; *(p++) = 't'; ++len; break;
363 case '\r':
364 *(p++) = '\\'; *(p++) = 'r'; ++len; break;
365 default:
366 *(p++) = c;
367 }
368
369 ++len;
370 }
371
372 *p = 0;
373
374 return buf;
375 }
376
_dumpBytes(FILE * f,int length,int restore)377 void _dumpBytes(FILE *f, int length, int restore)
378 {
379 int j=0, i, k, l=0, offset=0;
380 unsigned char buf[16];
381
382 if(length<=0)
383 return;
384
385 if(restore)
386 offset = ftell(f);
387
388 putchar('\n');
389
390 for(;; ++l)
391 {
392 printf("%03x0: ", l);
393 for(i=0; i<16; ++i)
394 {
395 if(i==8) putchar(' ');
396
397 printf("%02x ", buf[i] = readUInt8(f));
398 ++j;
399
400 if(j==length)
401 break;
402 }
403
404 if(j==length)
405 {
406 for(k=i+1; k<16; ++k)
407 printf(" ");
408
409 if(k==8) putchar(' ');
410
411 ++i;
412 }
413
414 printf(" ");
415
416 for(k=0; k<i; ++k)
417 {
418 if(k==8) putchar(' ');
419
420 if((buf[k] > 31) && (buf[k] < 128))
421 putchar(buf[k]);
422 else
423 putchar('.');
424 }
425
426 putchar('\n');
427
428 if(j==length)
429 break;
430 }
431 putchar('\n');
432 putchar('\n');
433
434 if(restore) {
435 fseek(f,offset, SEEK_SET);
436 fileOffset = offset;
437 }
438 }
439
dumpBytes(FILE * f,int length)440 void dumpBytes(FILE *f, int length)
441 {
442 _dumpBytes(f, length, 0 );
443 }
444
peekBytes(FILE * f,int length)445 void peekBytes(FILE *f, int length)
446 {
447 _dumpBytes(f, length, 1 );
448 }
449
dumpBuffer(unsigned char * buf,int length)450 void dumpBuffer(unsigned char *buf, int length)
451 {
452 int j=0, i, k, l=0;
453
454 if(length<=0)
455 return;
456
457 putchar('\n');
458
459 for(;; ++l)
460 {
461 printf("%03x0: ", l);
462
463 for(i=0; i<16; ++i)
464 {
465 if(i==8) putchar(' ');
466
467 printf("%02x ", buf[16*l+i]);
468 ++j;
469
470 if(j==length)
471 break;
472 }
473
474 if(j==length)
475 {
476 for(k=i+1; k<16; ++k)
477 printf(" ");
478
479 if(k==8) putchar(' ');
480
481 ++i;
482 }
483
484 printf(" ");
485
486 for(k=0; k<i; ++k)
487 {
488 if(k==8) putchar(' ');
489
490 if((buf[16*l+k] > 31) && (buf[16*l+k] < 128))
491 putchar(buf[16*l+k]);
492 else
493 putchar('.');
494 }
495
496 putchar('\n');
497
498 if(j==length)
499 break;
500 }
501
502 putchar('\n');
503 putchar('\n');
504 }
505
silentSkipBytes(FILE * f,int length)506 void silentSkipBytes(FILE *f, int length)
507 {
508 for(; length>0; --length)
509 readUInt8(f);
510 }
511
512
513