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
28 #include "swfdec_bits.h"
29 #include "swfdec_debug.h"
30 #include "swfdec_decoder.h"
31 #include "swfdec_rect.h"
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
;
43 bits
->end
= buffer
->data
+ buffer
->length
;
47 swfdec_bits_left (SwfdecBits
*b
)
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"); \
62 #define SWFDEC_BYTES_CHECK(b,n) G_STMT_START { \
63 swfdec_bits_syncbits (b); \
64 SWFDEC_BITS_CHECK (b, 8 * n); \
68 swfdec_bits_getbit (SwfdecBits
* b
)
72 SWFDEC_BITS_CHECK (b
, 1);
74 r
= ((*b
->ptr
) >> (7 - b
->idx
)) & 1;
86 swfdec_bits_getbits (SwfdecBits
* b
, unsigned int n
)
91 SWFDEC_BITS_CHECK (b
, n
);
94 i
= MIN (n
, 8 - b
->idx
);
96 r
|= ((*b
->ptr
) >> (8 - i
- b
->idx
)) & ((1 << i
) - 1);
112 swfdec_bits_peekbits (SwfdecBits
* b
, unsigned int n
)
116 return swfdec_bits_getbits (&tmp
, n
);
120 swfdec_bits_getsbits (SwfdecBits
* b
, unsigned int n
)
124 SWFDEC_BITS_CHECK (b
, n
);
128 r
= -swfdec_bits_getbit (b
);
129 r
= (r
<< (n
- 1)) | swfdec_bits_getbits (b
, n
- 1);
134 swfdec_bits_peek_u8 (SwfdecBits
* b
)
136 SWFDEC_BYTES_CHECK (b
, 1);
142 swfdec_bits_get_u8 (SwfdecBits
* b
)
144 SWFDEC_BYTES_CHECK (b
, 1);
150 swfdec_bits_get_u16 (SwfdecBits
* b
)
154 SWFDEC_BYTES_CHECK (b
, 2);
156 r
= b
->ptr
[0] | (b
->ptr
[1] << 8);
163 swfdec_bits_get_s16 (SwfdecBits
* b
)
167 SWFDEC_BYTES_CHECK (b
, 2);
169 r
= b
->ptr
[0] | (b
->ptr
[1] << 8);
176 swfdec_bits_get_be_u16 (SwfdecBits
* b
)
180 SWFDEC_BYTES_CHECK (b
, 2);
182 r
= (b
->ptr
[0] << 8) | b
->ptr
[1];
189 swfdec_bits_get_u32 (SwfdecBits
* b
)
193 SWFDEC_BYTES_CHECK (b
, 4);
195 r
= b
->ptr
[0] | (b
->ptr
[1] << 8) | (b
->ptr
[2] << 16) | (b
->ptr
[3] << 24);
202 swfdec_bits_get_float (SwfdecBits
* b
)
209 SWFDEC_BYTES_CHECK (b
, 4);
211 conv
.i
= *((gint32
*) b
->ptr
);
214 conv
.i
= GINT32_FROM_LE (conv
.i
);
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))"
228 swfdec_bits_double_to_host (double in
)
236 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
239 conv
.i
[0] = conv
.i
[1];
243 conv
.i
[0] = GUINT32_FROM_LE (conv
.i
[0]);
244 conv
.i
[1] = GUINT32_FROM_LE (conv
.i
[1]);
250 swfdec_bits_get_double (SwfdecBits
* b
)
254 SWFDEC_BYTES_CHECK (b
, 8);
256 d
= *((double *) b
->ptr
);
258 d
= swfdec_bits_double_to_host (d
);
264 swfdec_bits_syncbits (SwfdecBits
* b
)
273 swfdec_bits_get_color_transform (SwfdecBits
* bits
, SwfdecColorTransform
* ct
)
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);
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
);
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
);
308 swfdec_bits_get_matrix (SwfdecBits
* bits
, cairo_matrix_t
*matrix
)
312 int n_translate_bits
;
316 swfdec_bits_syncbits (bits
);
318 has_scale
= swfdec_bits_getbit (bits
);
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
;
328 SWFDEC_LOG ("no scalefactors given");
332 has_rotate
= swfdec_bits_getbit (bits
);
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
;
342 SWFDEC_LOG ("no rotation");
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
;
362 matrix
->yx
+= (matrix
->yx
>= 0) ? EPSILON
: -EPSILON
;
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
;
375 swfdec_bits_get_string (SwfdecBits
* bits
)
377 const char *s
= swfdec_bits_skip_string (bits
);
383 swfdec_bits_skip_string (SwfdecBits
*bits
)
389 swfdec_bits_syncbits (bits
);
390 end
= memchr (bits
->ptr
, 0, bits
->end
- bits
->ptr
);
392 SWFDEC_ERROR ("could not parse string");
396 len
= end
- (const char *) bits
->ptr
;
397 s
= (char *) bits
->ptr
;
399 bits
->ptr
+= len
+ 1;
405 swfdec_bits_get_string_length (SwfdecBits
* bits
, unsigned int len
)
409 SWFDEC_BYTES_CHECK (bits
, len
);
411 ret
= g_strndup ((char *) bits
->ptr
, len
);
417 swfdec_bits_get_color (SwfdecBits
* bits
)
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);
429 swfdec_bits_get_rgba (SwfdecBits
* bits
)
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
);
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
);
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
);
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
);
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
);
494 swfdec_bits_get_rect (SwfdecBits
* bits
, SwfdecRect
*rect
)
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:
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
515 * Returns: the new #SwfdecBuffer
518 swfdec_bits_get_buffer (SwfdecBits
*bits
, int len
)
520 SwfdecBuffer
*buffer
;
522 g_return_val_if_fail (len
> 0 || len
== -1, NULL
);
525 SWFDEC_BYTES_CHECK (bits
, (unsigned int) len
);
527 swfdec_bits_syncbits (bits
);
528 len
= bits
->end
- bits
->ptr
;
531 buffer
= swfdec_buffer_new_subbuffer (bits
->buffer
, bits
->ptr
- bits
->buffer
->data
, len
);