implement breakpoint API (breakpoints don't actually trigger yet)
[swfdec.git] / libswfdec / swfdec_bits.c
blobe14106b91f9a44c34be520618acf292adc7ff970
1 /* Swfdec
2 * Copyright (C) 2003-2006 David Schleef <ds@schleef.org>
3 * 2005-2006 Eric Anholt <eric@anholt.net>
4 * 2006 Benjamin Otte <otte@gnome.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
26 #include <string.h>
28 #include "swfdec_bits.h"
29 #include "swfdec_debug.h"
30 #include "swfdec_decoder.h"
31 #include "swfdec_rect.h"
34 void
35 swfdec_bits_init (SwfdecBits *bits, SwfdecBuffer *buffer)
37 g_return_if_fail (bits != NULL);
38 g_return_if_fail (buffer != NULL);
40 bits->buffer = buffer;
41 bits->ptr = buffer->data;
42 bits->idx = 0;
43 bits->end = buffer->data + buffer->length;
46 unsigned int
47 swfdec_bits_left (SwfdecBits *b)
49 if (b->ptr == NULL)
50 return 0;
51 g_assert (b->end >= b->ptr);
52 g_assert (b->end > b->ptr || b->idx == 0);
53 return (b->end - b->ptr) * 8 - b->idx;
56 #define SWFDEC_BITS_CHECK(b,n) G_STMT_START { \
57 if (swfdec_bits_left(b) < (n)) { \
58 SWFDEC_ERROR("reading past end of buffer"); \
59 return 0; \
60 } \
61 }G_STMT_END
62 #define SWFDEC_BYTES_CHECK(b,n) G_STMT_START { \
63 swfdec_bits_syncbits (b); \
64 SWFDEC_BITS_CHECK (b, 8 * n); \
65 } G_STMT_END
67 int
68 swfdec_bits_getbit (SwfdecBits * b)
70 int r;
72 SWFDEC_BITS_CHECK (b, 1);
74 r = ((*b->ptr) >> (7 - b->idx)) & 1;
76 b->idx++;
77 if (b->idx >= 8) {
78 b->ptr++;
79 b->idx = 0;
82 return r;
85 unsigned int
86 swfdec_bits_getbits (SwfdecBits * b, unsigned int n)
88 unsigned long r = 0;
89 unsigned int i;
91 SWFDEC_BITS_CHECK (b, n);
93 while (n > 0) {
94 i = MIN (n, 8 - b->idx);
95 r <<= i;
96 r |= ((*b->ptr) >> (8 - i - b->idx)) & ((1 << i) - 1);
97 n -= i;
98 if (i == 8) {
99 b->ptr++;
100 } else {
101 b->idx += i;
102 if (b->idx >= 8) {
103 b->ptr++;
104 b->idx = 0;
108 return r;
111 unsigned int
112 swfdec_bits_peekbits (SwfdecBits * b, unsigned int n)
114 SwfdecBits tmp = *b;
116 return swfdec_bits_getbits (&tmp, n);
120 swfdec_bits_getsbits (SwfdecBits * b, unsigned int n)
122 unsigned long r = 0;
124 SWFDEC_BITS_CHECK (b, n);
126 if (n == 0)
127 return 0;
128 r = -swfdec_bits_getbit (b);
129 r = (r << (n - 1)) | swfdec_bits_getbits (b, n - 1);
130 return r;
133 unsigned int
134 swfdec_bits_peek_u8 (SwfdecBits * b)
136 SWFDEC_BYTES_CHECK (b, 1);
138 return *b->ptr;
141 unsigned int
142 swfdec_bits_get_u8 (SwfdecBits * b)
144 SWFDEC_BYTES_CHECK (b, 1);
146 return *b->ptr++;
149 unsigned int
150 swfdec_bits_get_u16 (SwfdecBits * b)
152 unsigned int r;
154 SWFDEC_BYTES_CHECK (b, 2);
156 r = b->ptr[0] | (b->ptr[1] << 8);
157 b->ptr += 2;
159 return r;
163 swfdec_bits_get_s16 (SwfdecBits * b)
165 short r;
167 SWFDEC_BYTES_CHECK (b, 2);
169 r = b->ptr[0] | (b->ptr[1] << 8);
170 b->ptr += 2;
172 return r;
175 unsigned int
176 swfdec_bits_get_be_u16 (SwfdecBits * b)
178 unsigned int r;
180 SWFDEC_BYTES_CHECK (b, 2);
182 r = (b->ptr[0] << 8) | b->ptr[1];
183 b->ptr += 2;
185 return r;
188 unsigned int
189 swfdec_bits_get_u32 (SwfdecBits * b)
191 unsigned int r;
193 SWFDEC_BYTES_CHECK (b, 4);
195 r = b->ptr[0] | (b->ptr[1] << 8) | (b->ptr[2] << 16) | (b->ptr[3] << 24);
196 b->ptr += 4;
198 return r;
201 float
202 swfdec_bits_get_float (SwfdecBits * b)
204 union {
205 gint32 i;
206 float f;
207 } conv;
209 SWFDEC_BYTES_CHECK (b, 4);
211 conv.i = *((gint32 *) b->ptr);
212 b->ptr += 4;
214 conv.i = GINT32_FROM_LE (conv.i);
216 return conv.f;
219 /* fixup mad byte ordering of doubles in flash files.
220 * If little endian x86 byte order is 0 1 2 3 4 5 6 7 and PPC32 byte order is
221 * 7 6 5 4 3 2 1 0, then Flash uses 4 5 6 7 0 1 2 3.
222 * If your architecture has a different byte ordering for storing doubles,
223 * this conversion function will fail. To find out your byte ordering, you can
224 * use this command line:
225 * python -c "import struct; print struct.unpack('8c', struct.pack('d', 7.949928895127363e-275))"
227 static double
228 swfdec_bits_double_to_host (double in)
230 union {
231 guint32 i[2];
232 double d;
233 } conv;
235 conv.d = in;
236 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
238 int tmp = conv.i[0];
239 conv.i[0] = conv.i[1];
240 conv.i[1] = tmp;
242 #else
243 conv.i[0] = GUINT32_FROM_LE (conv.i[0]);
244 conv.i[1] = GUINT32_FROM_LE (conv.i[1]);
245 #endif
246 return conv.d;
249 double
250 swfdec_bits_get_double (SwfdecBits * b)
252 double d;
254 SWFDEC_BYTES_CHECK (b, 8);
256 d = *((double *) b->ptr);
257 b->ptr += 8;
258 d = swfdec_bits_double_to_host (d);
260 return d;
263 void
264 swfdec_bits_syncbits (SwfdecBits * b)
266 if (b->idx) {
267 b->ptr++;
268 b->idx = 0;
272 void
273 swfdec_bits_get_color_transform (SwfdecBits * bits, SwfdecColorTransform * ct)
275 int has_add;
276 int has_mult;
277 int n_bits;
279 swfdec_bits_syncbits (bits);
280 has_add = swfdec_bits_getbit (bits);
281 has_mult = swfdec_bits_getbit (bits);
282 n_bits = swfdec_bits_getbits (bits, 4);
283 if (has_mult) {
284 ct->ra = swfdec_bits_getsbits (bits, n_bits);
285 ct->ga = swfdec_bits_getsbits (bits, n_bits);
286 ct->ba = swfdec_bits_getsbits (bits, n_bits);
287 ct->aa = swfdec_bits_getsbits (bits, n_bits);
288 } else {
289 ct->ra = 256;
290 ct->ga = 256;
291 ct->ba = 256;
292 ct->aa = 256;
294 if (has_add) {
295 ct->rb = swfdec_bits_getsbits (bits, n_bits);
296 ct->gb = swfdec_bits_getsbits (bits, n_bits);
297 ct->bb = swfdec_bits_getsbits (bits, n_bits);
298 ct->ab = swfdec_bits_getsbits (bits, n_bits);
299 } else {
300 ct->rb = 0;
301 ct->gb = 0;
302 ct->bb = 0;
303 ct->ab = 0;
307 void
308 swfdec_bits_get_matrix (SwfdecBits * bits, cairo_matrix_t *matrix)
310 int has_scale;
311 int has_rotate;
312 int n_translate_bits;
313 int translate_x;
314 int translate_y;
316 swfdec_bits_syncbits (bits);
318 has_scale = swfdec_bits_getbit (bits);
319 if (has_scale) {
320 int n_scale_bits = swfdec_bits_getbits (bits, 5);
321 int scale_x = swfdec_bits_getsbits (bits, n_scale_bits);
322 int scale_y = swfdec_bits_getsbits (bits, n_scale_bits);
324 SWFDEC_LOG ("scalefactors: x = %d, y = %d", scale_x, scale_y);
325 matrix->xx = scale_x / SWFDEC_FIXED_SCALE_FACTOR;
326 matrix->yy = scale_y / SWFDEC_FIXED_SCALE_FACTOR;
327 } else {
328 SWFDEC_LOG ("no scalefactors given");
329 matrix->xx = 1.0;
330 matrix->yy = 1.0;
332 has_rotate = swfdec_bits_getbit (bits);
333 if (has_rotate) {
334 int n_rotate_bits = swfdec_bits_getbits (bits, 5);
335 int rotate_skew0 = swfdec_bits_getsbits (bits, n_rotate_bits);
336 int rotate_skew1 = swfdec_bits_getsbits (bits, n_rotate_bits);
338 SWFDEC_LOG ("skew: xy = %d, yx = %d", rotate_skew1, rotate_skew0);
339 matrix->xy = rotate_skew1 / SWFDEC_FIXED_SCALE_FACTOR;
340 matrix->yx = rotate_skew0 / SWFDEC_FIXED_SCALE_FACTOR;
341 } else {
342 SWFDEC_LOG ("no rotation");
343 matrix->xy = 0.0;
344 matrix->yx = 0.0;
347 cairo_matrix_t tmp = *matrix;
348 while (cairo_matrix_invert (&tmp)) {
349 SWFDEC_WARNING ("matrix not invertible, adding epsilon to smallest member");
350 /* add epsilon at point closest to zero */
351 #define EPSILON (1.0 / SWFDEC_FIXED_SCALE_FACTOR)
352 if (ABS (matrix->xx) <= ABS (matrix->xy) &&
353 ABS (matrix->xx) <= ABS (matrix->yx) &&
354 ABS (matrix->xx) <= ABS (matrix->yy))
355 matrix->xx += (matrix->xx >= 0) ? EPSILON : -EPSILON;
356 else if (ABS (matrix->yy) <= ABS (matrix->xy) &&
357 ABS (matrix->yy) <= ABS (matrix->yx))
358 matrix->yy += (matrix->yy >= 0) ? EPSILON : -EPSILON;
359 else if (ABS (matrix->xy) <= ABS (matrix->yx))
360 matrix->xy += (matrix->xy >= 0) ? EPSILON : -EPSILON;
361 else
362 matrix->yx += (matrix->yx >= 0) ? EPSILON : -EPSILON;
363 tmp = *matrix;
366 n_translate_bits = swfdec_bits_getbits (bits, 5);
367 translate_x = swfdec_bits_getsbits (bits, n_translate_bits);
368 translate_y = swfdec_bits_getsbits (bits, n_translate_bits);
370 matrix->x0 = translate_x;
371 matrix->y0 = translate_y;
374 char *
375 swfdec_bits_get_string (SwfdecBits * bits)
377 const char *s = swfdec_bits_skip_string (bits);
379 return g_strdup (s);
382 const char *
383 swfdec_bits_skip_string (SwfdecBits *bits)
385 char *s;
386 const char *end;
387 unsigned int len;
389 swfdec_bits_syncbits (bits);
390 end = memchr (bits->ptr, 0, bits->end - bits->ptr);
391 if (end == NULL) {
392 SWFDEC_ERROR ("could not parse string");
393 return NULL;
396 len = end - (const char *) bits->ptr;
397 s = (char *) bits->ptr;
399 bits->ptr += len + 1;
401 return s;
404 char *
405 swfdec_bits_get_string_length (SwfdecBits * bits, unsigned int len)
407 char *ret;
409 SWFDEC_BYTES_CHECK (bits, len);
411 ret = g_strndup ((char *) bits->ptr, len);
412 bits->ptr += len;
413 return ret;
416 unsigned int
417 swfdec_bits_get_color (SwfdecBits * bits)
419 int r, g, b;
421 r = swfdec_bits_get_u8 (bits);
422 g = swfdec_bits_get_u8 (bits);
423 b = swfdec_bits_get_u8 (bits);
425 return SWF_COLOR_COMBINE (r, g, b, 0xff);
428 unsigned int
429 swfdec_bits_get_rgba (SwfdecBits * bits)
431 int r, g, b, a;
433 r = swfdec_bits_get_u8 (bits);
434 g = swfdec_bits_get_u8 (bits);
435 b = swfdec_bits_get_u8 (bits);
436 a = swfdec_bits_get_u8 (bits);
438 return SWF_COLOR_COMBINE (r, g, b, a);
441 SwfdecGradient *
442 swfdec_bits_get_gradient (SwfdecBits * bits)
444 SwfdecGradient *grad;
445 unsigned int i, n_gradients;
447 n_gradients = swfdec_bits_get_u8 (bits);
448 grad = g_malloc (sizeof (SwfdecGradient) +
449 sizeof (SwfdecGradientEntry) * (n_gradients - 1));
450 grad->n_gradients = n_gradients;
451 for (i = 0; i < n_gradients; i++) {
452 grad->array[i].ratio = swfdec_bits_get_u8 (bits);
453 grad->array[i].color = swfdec_bits_get_color (bits);
455 return grad;
458 SwfdecGradient *
459 swfdec_bits_get_gradient_rgba (SwfdecBits * bits)
461 SwfdecGradient *grad;
462 unsigned int i, n_gradients;
464 n_gradients = swfdec_bits_get_u8 (bits);
465 grad = g_malloc (sizeof (SwfdecGradient) +
466 sizeof (SwfdecGradientEntry) * (n_gradients - 1));
467 grad->n_gradients = n_gradients;
468 for (i = 0; i < n_gradients; i++) {
469 grad->array[i].ratio = swfdec_bits_get_u8 (bits);
470 grad->array[i].color = swfdec_bits_get_rgba (bits);
472 return grad;
475 SwfdecGradient *
476 swfdec_bits_get_morph_gradient (SwfdecBits * bits)
478 SwfdecGradient *grad;
479 unsigned int i, n_gradients;
481 n_gradients = swfdec_bits_get_u8 (bits);
482 n_gradients *= 2;
483 grad = g_malloc (sizeof (SwfdecGradient) +
484 sizeof (SwfdecGradientEntry) * (n_gradients - 1));
485 grad->n_gradients = n_gradients;
486 for (i = 0; i < n_gradients; i++) {
487 grad->array[i].ratio = swfdec_bits_get_u8 (bits);
488 grad->array[i].color = swfdec_bits_get_rgba (bits);
490 return grad;
493 void
494 swfdec_bits_get_rect (SwfdecBits * bits, SwfdecRect *rect)
496 int nbits;
498 swfdec_bits_syncbits (bits);
499 nbits = swfdec_bits_getbits (bits, 5);
501 rect->x0 = swfdec_bits_getsbits (bits, nbits);
502 rect->x1 = swfdec_bits_getsbits (bits, nbits);
503 rect->y0 = swfdec_bits_getsbits (bits, nbits);
504 rect->y1 = swfdec_bits_getsbits (bits, nbits);
508 * swfdec_bits_get_buffer:
509 * @bits: #SwfdecBits
510 * @len: length of buffer or -1 for maximum
512 * Gets the contents of the next @len bytes of @bits and buts them in a new
513 * subbuffer.
515 * Returns: the new #SwfdecBuffer
517 SwfdecBuffer *
518 swfdec_bits_get_buffer (SwfdecBits *bits, int len)
520 SwfdecBuffer *buffer;
522 g_return_val_if_fail (len > 0 || len == -1, NULL);
524 if (len > 0) {
525 SWFDEC_BYTES_CHECK (bits, (unsigned int) len);
526 } else {
527 swfdec_bits_syncbits (bits);
528 len = bits->end - bits->ptr;
529 g_assert (len > 0);
531 buffer = swfdec_buffer_new_subbuffer (bits->buffer, bits->ptr - bits->buffer->data, len);
532 bits->ptr += len;
533 return buffer;