2 * Copyright (C) 2003-2006 David Schleef <ds@schleef.org>
3 * 2005-2006 Eric Anholt <eric@anholt.net>
4 * 2006-2007 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
29 #include "swfdec_bits.h"
30 #include "swfdec_color.h"
31 #include "swfdec_debug.h"
32 #include "swfdec_rect.h"
35 #define SWFDEC_BITS_CHECK(b,n) G_STMT_START { \
36 if (swfdec_bits_left(b) < (n)) { \
37 SWFDEC_ERROR ("reading past end of buffer"); \
43 #define SWFDEC_BYTES_CHECK(b,n) G_STMT_START { \
44 g_assert (b->end >= b->ptr); \
45 g_assert (b->idx == 0); \
46 if ((unsigned long) (b->end - b->ptr) < n) { \
47 SWFDEC_ERROR ("reading past end of buffer"); \
56 * @bits: a #SwfdecBits
57 * @buffer: buffer to use for data or NULL
59 * initializes @bits for use with the data in @buffer. The buffer will not be
60 * referenced, so you are responsible for keeping it around while @bits is used.
63 swfdec_bits_init (SwfdecBits
*bits
, SwfdecBuffer
*buffer
)
65 g_return_if_fail (bits
!= NULL
);
68 bits
->buffer
= buffer
;
69 bits
->ptr
= buffer
->data
;
71 bits
->end
= buffer
->data
+ buffer
->length
;
73 memset (bits
, 0, sizeof (SwfdecBits
));
78 * swfdec_bits_init_bits:
79 * @bits: a #SwfdecBits
80 * @from: a #SwfdecBits to initialize from
81 * @bytes: number of bytes to move to @bits
83 * Initializes @bits for use with the next @bytes bytes from @from. If not
84 * enough bytes are available, less bytes will be available in @bits. @from
85 * will skip the bytes now available in @bits. If you want to know if this
86 * function moves enough bytes, you should ensure that enough data is
87 * available using swfdec_bits_left() before calling this function.
90 swfdec_bits_init_bits (SwfdecBits
*bits
, SwfdecBits
*from
, guint bytes
)
92 g_return_if_fail (bits
!= NULL
);
93 g_return_if_fail (from
!= NULL
);
94 g_return_if_fail (from
->idx
== 0);
96 bits
->buffer
= from
->buffer
;
97 bits
->ptr
= from
->ptr
;
98 if (bytes
> (guint
) (from
->end
- from
->ptr
))
99 bytes
= from
->end
- from
->ptr
;
100 bits
->end
= bits
->ptr
+ bytes
;
102 from
->ptr
= bits
->end
;
106 * swfdec_bits_init_data:
107 * @bits: the #SwfdecBits to initialize
108 * @data: data to initialize with
109 * @len: length of the data
111 * Initializes @bits for use with the given @data. All operations on @bits will
112 * return copies of the data, so after use, you can free the supplied data. Using
113 * %NULL for @data is valid if @len is 0.
116 swfdec_bits_init_data (SwfdecBits
*bits
, const guint8
*data
, guint len
)
118 g_return_if_fail (bits
!= NULL
);
119 g_return_if_fail (data
!= NULL
|| len
== 0);
124 bits
->end
= bits
->ptr
+ len
;
128 swfdec_bits_left (const SwfdecBits
*b
)
132 g_assert (b
->end
>= b
->ptr
);
133 g_assert (b
->end
> b
->ptr
|| b
->idx
== 0);
134 return (b
->end
- b
->ptr
) * 8 - b
->idx
;
138 swfdec_bits_getbit (SwfdecBits
* b
)
142 SWFDEC_BITS_CHECK (b
, 1);
144 r
= ((*b
->ptr
) >> (7 - b
->idx
)) & 1;
156 swfdec_bits_getbits (SwfdecBits
* b
, guint n
)
161 SWFDEC_BITS_CHECK (b
, n
);
164 i
= MIN (n
, 8 - b
->idx
);
166 r
|= ((*b
->ptr
) >> (8 - i
- b
->idx
)) & ((1 << i
) - 1);
182 swfdec_bits_peekbits (const SwfdecBits
* b
, guint n
)
186 return swfdec_bits_getbits (&tmp
, n
);
190 swfdec_bits_getsbits (SwfdecBits
* b
, guint n
)
194 SWFDEC_BITS_CHECK (b
, n
);
198 r
= -swfdec_bits_getbit (b
);
199 r
= (r
<< (n
- 1)) | swfdec_bits_getbits (b
, n
- 1);
204 swfdec_bits_peek_u8 (const SwfdecBits
* b
)
206 g_assert (b
->idx
== 0);
207 g_assert (b
->ptr
<= b
->end
);
208 if (b
->ptr
== b
->end
)
215 swfdec_bits_get_u8 (SwfdecBits
* b
)
217 SWFDEC_BYTES_CHECK (b
, 1);
223 swfdec_bits_get_u16 (SwfdecBits
* b
)
227 SWFDEC_BYTES_CHECK (b
, 2);
229 r
= b
->ptr
[0] | (b
->ptr
[1] << 8);
236 swfdec_bits_get_s16 (SwfdecBits
* b
)
240 SWFDEC_BYTES_CHECK (b
, 2);
242 r
= b
->ptr
[0] | (b
->ptr
[1] << 8);
249 swfdec_bits_get_u32 (SwfdecBits
* b
)
253 SWFDEC_BYTES_CHECK (b
, 4);
255 r
= b
->ptr
[0] | (b
->ptr
[1] << 8) | (b
->ptr
[2] << 16) | (b
->ptr
[3] << 24);
262 swfdec_bits_get_s32 (SwfdecBits
*b
)
264 return (gint32
) swfdec_bits_get_u32 (b
);
268 swfdec_bits_get_bu16 (SwfdecBits
*b
)
272 SWFDEC_BYTES_CHECK (b
, 2);
274 r
= (b
->ptr
[0] << 8) | b
->ptr
[1];
281 swfdec_bits_get_bu24 (SwfdecBits
*b
)
285 SWFDEC_BYTES_CHECK (b
, 3);
287 r
= (b
->ptr
[0] << 16) | (b
->ptr
[1] << 8) | b
->ptr
[2];
294 swfdec_bits_get_bu32 (SwfdecBits
*b
)
298 SWFDEC_BYTES_CHECK (b
, 4);
300 r
= (b
->ptr
[0] << 24) | (b
->ptr
[1] << 16) | (b
->ptr
[2] << 8) | b
->ptr
[3];
307 swfdec_bits_get_float (SwfdecBits
* b
)
314 SWFDEC_BYTES_CHECK (b
, 4);
316 conv
.i
= (b
->ptr
[3] << 24) | (b
->ptr
[2] << 16) | (b
->ptr
[1] << 8) | b
->ptr
[0];
322 /* fixup mad byte ordering of doubles in flash files.
323 * If little endian x86 byte order is 0 1 2 3 4 5 6 7 and PPC32 byte order is
324 * 7 6 5 4 3 2 1 0, then Flash uses 4 5 6 7 0 1 2 3.
325 * If your architecture has a different byte ordering for storing doubles,
326 * this conversion function will fail. To find out your byte ordering, you can
327 * use this command line:
328 * python -c "import struct; print struct.unpack('8c', struct.pack('d', 7.949928895127363e-275))"
331 swfdec_bits_get_double (SwfdecBits
* b
)
338 SWFDEC_BYTES_CHECK (b
, 8);
340 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
341 conv
.i
[1] = (b
->ptr
[3] << 24) | (b
->ptr
[2] << 16) | (b
->ptr
[1] << 8) | b
->ptr
[0];
342 conv
.i
[0] = (b
->ptr
[7] << 24) | (b
->ptr
[6] << 16) | (b
->ptr
[5] << 8) | b
->ptr
[4];
344 conv
.i
[0] = (b
->ptr
[3] << 24) | (b
->ptr
[2] << 16) | (b
->ptr
[1] << 8) | b
->ptr
[0];
345 conv
.i
[1] = (b
->ptr
[7] << 24) | (b
->ptr
[6] << 16) | (b
->ptr
[5] << 8) | b
->ptr
[4];
353 swfdec_bits_get_bdouble (SwfdecBits
* b
)
360 SWFDEC_BYTES_CHECK (b
, 8);
362 memcpy (&u
.u64
, b
->ptr
, 8);
365 u
.u64
= GUINT64_FROM_BE (u
.u64
);
371 swfdec_bits_syncbits (SwfdecBits
* b
)
380 swfdec_bits_get_color_transform (SwfdecBits
* bits
, SwfdecColorTransform
* ct
)
387 has_add
= swfdec_bits_getbit (bits
);
388 has_mult
= swfdec_bits_getbit (bits
);
389 n_bits
= swfdec_bits_getbits (bits
, 4);
391 ct
->ra
= swfdec_bits_getsbits (bits
, n_bits
);
392 ct
->ga
= swfdec_bits_getsbits (bits
, n_bits
);
393 ct
->ba
= swfdec_bits_getsbits (bits
, n_bits
);
394 ct
->aa
= swfdec_bits_getsbits (bits
, n_bits
);
402 ct
->rb
= swfdec_bits_getsbits (bits
, n_bits
);
403 ct
->gb
= swfdec_bits_getsbits (bits
, n_bits
);
404 ct
->bb
= swfdec_bits_getsbits (bits
, n_bits
);
405 ct
->ab
= swfdec_bits_getsbits (bits
, n_bits
);
412 swfdec_bits_syncbits (bits
);
416 swfdec_bits_get_matrix (SwfdecBits
* bits
, cairo_matrix_t
*matrix
,
417 cairo_matrix_t
*inverse
)
421 int n_translate_bits
;
423 has_scale
= swfdec_bits_getbit (bits
);
425 int n_scale_bits
= swfdec_bits_getbits (bits
, 5);
426 matrix
->xx
= SWFDEC_FIXED_TO_DOUBLE (swfdec_bits_getsbits (bits
, n_scale_bits
));
427 matrix
->yy
= SWFDEC_FIXED_TO_DOUBLE (swfdec_bits_getsbits (bits
, n_scale_bits
));
429 SWFDEC_LOG ("scalefactors: x = %d/65536, y = %d/65536",
430 SWFDEC_DOUBLE_TO_FIXED (matrix
->xx
), SWFDEC_DOUBLE_TO_FIXED (matrix
->yy
));
432 SWFDEC_LOG ("no scalefactors given");
436 has_rotate
= swfdec_bits_getbit (bits
);
438 int n_rotate_bits
= swfdec_bits_getbits (bits
, 5);
439 matrix
->yx
= SWFDEC_FIXED_TO_DOUBLE (swfdec_bits_getsbits (bits
, n_rotate_bits
));
440 matrix
->xy
= SWFDEC_FIXED_TO_DOUBLE (swfdec_bits_getsbits (bits
, n_rotate_bits
));
442 SWFDEC_LOG ("skew: xy = %d/65536, yx = %d/65536",
443 SWFDEC_DOUBLE_TO_FIXED (matrix
->xy
),
444 SWFDEC_DOUBLE_TO_FIXED (matrix
->yx
));
446 SWFDEC_LOG ("no rotation");
450 n_translate_bits
= swfdec_bits_getbits (bits
, 5);
451 matrix
->x0
= swfdec_bits_getsbits (bits
, n_translate_bits
);
452 matrix
->y0
= swfdec_bits_getsbits (bits
, n_translate_bits
);
454 swfdec_matrix_ensure_invertible (matrix
, inverse
);
455 swfdec_bits_syncbits (bits
);
459 swfdec_bits_skip_string (SwfdecBits
*bits
)
465 SWFDEC_BYTES_CHECK (bits
, 1);
466 end
= memchr (bits
->ptr
, 0, bits
->end
- bits
->ptr
);
468 SWFDEC_ERROR ("could not parse string");
472 len
= end
- (const char *) bits
->ptr
;
473 s
= (char *) bits
->ptr
;
474 bits
->ptr
+= len
+ 1;
480 * swfdec_bits_get_string:
481 * @bits: a #SwfdecBits
482 * @version: Flash player version
484 * Prior to Flash 6, strings used to be encoded as LATIN1. Since Flash 6,
485 * strings are encoded as UTF-8. This version does that check automatically
486 * and converts strings to UTF-8.
488 * Returns: a UTF-8 encoded string or %NULL on error
491 swfdec_bits_get_string (SwfdecBits
*bits
, guint version
)
495 g_return_val_if_fail (bits
!= NULL
, NULL
);
497 s
= swfdec_bits_skip_string (bits
);
502 char *ret
= g_convert (s
, -1, "UTF-8", "LATIN1", NULL
, NULL
, NULL
);
504 g_warning ("Could not convert string from LATIN1 to UTF-8");
507 if (!g_utf8_validate (s
, -1, NULL
)) {
508 SWFDEC_ERROR ("parsed string is not valid utf-8");
516 * swfdec_bits_skip_bytes:
517 * @bits: a #SwfdecBits
518 * @n_bytes: number of bytes to skip
520 * Skips up to @n_bytes bytes in @bits. If not enough bytes are available,
521 * only the available amount is skipped and a warning is printed.
523 * Returns: the number of bytes actually skipped
526 swfdec_bits_skip_bytes (SwfdecBits
*bits
, guint n_bytes
)
528 g_assert (bits
->idx
== 0);
529 if ((guint
) (bits
->end
- bits
->ptr
) < n_bytes
) {
530 SWFDEC_WARNING ("supposed to skip %u bytes, but only %td available",
531 n_bytes
, bits
->end
- bits
->ptr
);
532 n_bytes
= bits
->end
- bits
->ptr
;
534 bits
->ptr
+= n_bytes
;
539 * swfdec_bits_get_string_length:
540 * @bits: a #SwfdecBits
541 * @len: number of bytes to read
542 * @version: flash version number
544 * Reads the next @len bytes (not characters!) into a string and validates
545 * its encoding is correct based on supplied version number.
547 * Returns: a new UTF-8 string or %NULL on error
550 swfdec_bits_get_string_length (SwfdecBits
* bits
, guint len
, guint version
)
555 return g_strdup ("");
556 SWFDEC_BYTES_CHECK (bits
, len
);
558 ret
= g_strndup ((char *) bits
->ptr
, len
);
562 char *tmp
= g_convert (ret
, -1, "UTF-8", "LATIN1", NULL
, NULL
, NULL
);
566 if (!g_utf8_validate (ret
, -1, NULL
)) {
567 SWFDEC_ERROR ("parsed string is not valid utf-8");
577 swfdec_bits_get_color (SwfdecBits
* bits
)
581 r
= swfdec_bits_get_u8 (bits
);
582 g
= swfdec_bits_get_u8 (bits
);
583 b
= swfdec_bits_get_u8 (bits
);
585 return SWFDEC_COLOR_COMBINE (r
, g
, b
, 0xff);
589 swfdec_bits_get_rgba (SwfdecBits
* bits
)
593 r
= swfdec_bits_get_u8 (bits
);
594 g
= swfdec_bits_get_u8 (bits
);
595 b
= swfdec_bits_get_u8 (bits
);
596 a
= swfdec_bits_get_u8 (bits
);
598 return SWFDEC_COLOR_COMBINE (r
, g
, b
, a
);
602 swfdec_bits_get_rect (SwfdecBits
* bits
, SwfdecRect
*rect
)
606 nbits
= swfdec_bits_getbits (bits
, 5);
607 rect
->x0
= swfdec_bits_getsbits (bits
, nbits
);
608 rect
->x1
= swfdec_bits_getsbits (bits
, nbits
);
609 rect
->y0
= swfdec_bits_getsbits (bits
, nbits
);
610 rect
->y1
= swfdec_bits_getsbits (bits
, nbits
);
612 swfdec_bits_syncbits (bits
);
616 * swfdec_bits_get_buffer:
618 * @len: length of buffer or -1 for maximum
620 * Gets the contents of the next @len bytes of @bits and buts them in a new
623 * Returns: the new #SwfdecBuffer or %NULL if the requested amount of data
627 swfdec_bits_get_buffer (SwfdecBits
*bits
, int len
)
629 SwfdecBuffer
*buffer
;
631 g_return_val_if_fail (len
>= -1, NULL
);
634 SWFDEC_BYTES_CHECK (bits
, (guint
) len
);
636 g_assert (bits
->idx
== 0);
637 len
= bits
->end
- bits
->ptr
;
641 return swfdec_buffer_new (0);
643 buffer
= swfdec_buffer_new_subbuffer (bits
->buffer
, bits
->ptr
- bits
->buffer
->data
, len
);
645 buffer
= swfdec_buffer_new (len
);
646 memcpy (buffer
->data
, bits
->ptr
, len
);
653 swfdec_bits_zalloc (void *opaque
, guint items
, guint size
)
655 return g_malloc (items
* size
);
659 swfdec_bits_zfree (void *opaque
, void *addr
)
665 * swfdec_bits_decompress:
666 * @bits: a #SwfdecBits
667 * @compressed: number of bytes to decompress or -1 for the rest
668 * @decompressed: number of bytes to expect in the decompressed result or -1
671 * Decompresses the next @compressed bytes of data in @bits using the zlib
672 * decompression algorithm and returns the result in a buffer. If @decompressed
673 * was set and not enough data is available, the return buffer will be filled
676 * Returns: a new #SwfdecBuffer containing the decompressed data or NULL on
677 * failure. If @decompressed > 0, the buffer's length will be @decompressed.
680 swfdec_bits_decompress (SwfdecBits
*bits
, int compressed
, int decompressed
)
683 SwfdecBuffer
*buffer
;
686 g_return_val_if_fail (bits
!= NULL
, NULL
);
687 g_return_val_if_fail (compressed
>= -1, NULL
);
688 g_return_val_if_fail (decompressed
> 0 || decompressed
== -1, NULL
);
690 /* prepare the bits structure */
691 if (compressed
> 0) {
692 SWFDEC_BYTES_CHECK (bits
, (guint
) compressed
);
694 g_assert (bits
->idx
== 0);
695 compressed
= bits
->end
- bits
->ptr
;
696 g_assert (compressed
>= 0);
701 z
.zalloc
= swfdec_bits_zalloc
;
702 z
.zfree
= swfdec_bits_zfree
;
704 z
.next_in
= (Bytef
*) bits
->ptr
;
705 z
.avail_in
= compressed
;
706 result
= inflateInit (&z
);
707 if (result
!= Z_OK
) {
708 SWFDEC_ERROR ("Error initialising zlib: %d %s", result
, z
.msg
? z
.msg
: "");
711 buffer
= swfdec_buffer_new (decompressed
> 0 ? decompressed
: compressed
* 2);
712 z
.next_out
= buffer
->data
;
713 z
.avail_out
= buffer
->length
;
715 result
= inflate (&z
, decompressed
> 0 ? Z_FINISH
: 0);
720 if (decompressed
< 0) {
721 buffer
->data
= g_realloc (buffer
->data
, buffer
->length
+ compressed
);
722 buffer
->length
+= compressed
;
723 z
.next_out
= buffer
->data
+ z
.total_out
;
724 z
.avail_out
= buffer
->length
- z
.total_out
;
727 /* else fall through */
729 SWFDEC_ERROR ("error decompressing data: inflate returned %d %s",
730 result
, z
.msg
? z
.msg
: "");
731 swfdec_buffer_unref (buffer
);
736 if (decompressed
< 0) {
737 buffer
->length
= z
.total_out
;
739 if (buffer
->length
> z
.total_out
) {
740 SWFDEC_WARNING ("Not enough data decompressed: %lu instead of %"G_GSIZE_FORMAT
" expected",
741 (gulong
) z
.total_out
, buffer
->length
);
742 memset (buffer
->data
+ z
.total_out
, 0, buffer
->length
- z
.total_out
);
745 result
= inflateEnd (&z
);
746 if (result
!= Z_OK
) {
747 SWFDEC_ERROR ("error in inflateEnd: %d %s", result
, z
.msg
? z
.msg
: "");
749 bits
->ptr
+= compressed
;
753 bits
->ptr
+= compressed
;