2 * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
26 #include "swfdec_bots.h"
29 swfdec_bots_open (void)
31 SwfdecBots
*bots
= g_new0 (SwfdecBots
, 1);
33 bots
->data
= g_malloc (SWFDEC_OUT_INITIAL
);
34 bots
->ptr
= bots
->data
;
35 bots
->end
= bots
->data
+ SWFDEC_OUT_INITIAL
;
41 swfdec_bots_syncbits (SwfdecBots
*bots
)
43 g_return_if_fail (bots
!= NULL
);
52 swfdec_bots_close (SwfdecBots
*bots
)
56 g_return_val_if_fail (bots
!= NULL
, NULL
);
58 swfdec_bots_syncbits (bots
);
60 buffer
= swfdec_buffer_new_for_data (bots
->data
, bots
->ptr
- bots
->data
);
68 swfdec_bots_free (SwfdecBots
*bots
)
70 g_return_if_fail (bots
!= NULL
);
77 swfdec_bots_get_bits (SwfdecBots
*bots
)
79 g_return_val_if_fail (bots
!= NULL
, 0);
81 return (bots
->ptr
- bots
->data
) * 8 + bots
->idx
;
85 swfdec_bots_get_bytes (SwfdecBots
*bots
)
87 g_return_val_if_fail (bots
!= NULL
, 0);
89 g_assert (bots
->idx
== 0);
91 return swfdec_bots_get_bits (bots
) / 8;
95 swfdec_bots_left (SwfdecBots
*bots
)
97 g_return_val_if_fail (bots
!= NULL
, 0);
99 return (bots
->end
- bots
->ptr
) * 8 - bots
->idx
;
103 swfdec_bots_ensure_bits (SwfdecBots
*bots
, unsigned int bits
)
105 unsigned int current
, taken
, needed
;
107 g_return_if_fail (bots
!= NULL
);
109 current
= swfdec_bots_left (bots
);
112 taken
= bots
->ptr
- bots
->data
;
113 needed
= (bits
- current
+ 7) / 8;
114 needed
+= SWFDEC_OUT_STEP
;
115 needed
-= needed
% SWFDEC_OUT_STEP
;
116 needed
+= bots
->end
- bots
->data
;
117 bots
->data
= g_realloc (bots
->data
, needed
);
118 bots
->ptr
= bots
->data
+ taken
;
119 bots
->end
= bots
->data
+ needed
;
123 swfdec_bots_prepare_bytes (SwfdecBots
*bots
, unsigned int bytes
)
125 g_return_if_fail (bots
!= NULL
);
127 swfdec_bots_syncbits (bots
);
128 swfdec_bots_ensure_bits (bots
, bytes
* 8);
132 swfdec_bots_put_data (SwfdecBots
*bots
, const guint8
*data
, guint length
)
134 g_return_if_fail (bots
!= NULL
);
136 swfdec_bots_prepare_bytes (bots
, length
);
137 memcpy (bots
->ptr
, data
, length
);
142 swfdec_bots_put_buffer (SwfdecBots
*bots
, SwfdecBuffer
*buffer
)
144 g_return_if_fail (bots
!= NULL
);
146 swfdec_bots_prepare_bytes (bots
, buffer
->length
);
147 memcpy (bots
->ptr
, buffer
->data
, buffer
->length
);
148 bots
->ptr
+= buffer
->length
;
152 swfdec_bots_put_bots (SwfdecBots
*bots
, SwfdecBots
*other
)
156 g_return_if_fail (bots
!= NULL
);
157 g_return_if_fail (other
!= NULL
);
159 bytes
= swfdec_bots_get_bytes (other
);
160 swfdec_bots_prepare_bytes (bots
, bytes
);
161 memcpy (bots
->ptr
, other
->data
, bytes
);
166 swfdec_bots_put_u8 (SwfdecBots
*bots
, guint i
)
168 g_return_if_fail (i
<= G_MAXUINT8
);
170 swfdec_bots_prepare_bytes (bots
, 1);
176 swfdec_bots_put_u16 (SwfdecBots
*bots
, guint i
)
178 g_return_if_fail (i
<= G_MAXUINT16
);
180 swfdec_bots_prepare_bytes (bots
, 2);
182 bots
->ptr
[1] = i
>> 8;
187 swfdec_bots_put_s16 (SwfdecBots
*bots
, int i
)
189 g_return_if_fail (i
>= G_MININT16
&& i
<= G_MAXINT16
);
191 swfdec_bots_prepare_bytes (bots
, 2);
193 bots
->ptr
[1] = i
>> 8;
198 swfdec_bots_put_u32 (SwfdecBots
*bots
, guint i
)
200 g_return_if_fail (i
<= G_MAXUINT32
);
202 swfdec_bots_prepare_bytes (bots
, 4);
204 bots
->ptr
[1] = i
>> 8;
205 bots
->ptr
[2] = i
>> 16;
206 bots
->ptr
[3] = i
>> 24;
211 swfdec_bots_put_bit (SwfdecBots
*bots
, gboolean bit
)
213 g_return_if_fail (bots
!= NULL
);
215 swfdec_bots_put_bits (bots
, bit
? 1 : 0, 1);
219 swfdec_bots_put_bits (SwfdecBots
*bots
, guint bits
, guint n_bits
)
221 g_return_if_fail (bots
!= NULL
);
223 swfdec_bots_ensure_bits (bots
, n_bits
);
225 /* FIXME: implement this less braindead */
227 guint bits_now
= MIN (n_bits
, 8 - bots
->idx
);
228 guint value
= bits
>> (n_bits
- bits_now
);
230 /* clear data if necessary */
233 value
&= (1 << bits_now
) - 1;
234 value
<<= 8 - bots
->idx
- bits_now
;
236 bots
->idx
+= bits_now
;
237 g_assert (bots
->idx
<= 8);
238 if (bots
->idx
== 8) {
247 swfdec_bots_put_sbits (SwfdecBots
*bots
, int bits
, guint n_bits
)
249 g_return_if_fail (bots
!= NULL
);
251 swfdec_bots_put_bits (bots
, bits
, n_bits
);
255 swfdec_bots_put_string (SwfdecBots
*bots
, const char *s
)
259 g_return_if_fail (bots
!= NULL
);
260 g_return_if_fail (s
!= NULL
);
262 len
= strlen (s
) + 1;
264 swfdec_bots_prepare_bytes (bots
, len
);
265 memcpy (bots
->ptr
, s
, len
);
270 swfdec_bots_put_float (SwfdecBots
*bots
, float f
)
277 g_return_if_fail (bots
!= NULL
);
280 swfdec_bots_put_u32 (bots
, conv
.i
);
283 /* If little endian x86 byte order is 0 1 2 3 4 5 6 7 and PPC32 byte order is
284 * 7 6 5 4 3 2 1 0, then Flash uses 4 5 6 7 0 1 2 3. */
286 swfdec_bots_put_double (SwfdecBots
*bots
, double value
)
293 swfdec_bots_ensure_bits (bots
, 8);
297 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
298 swfdec_bots_put_u32 (bots
, conv
.i
[1]);
299 swfdec_bots_put_u32 (bots
, conv
.i
[0]);
301 swfdec_bots_put_u32 (bots
, GUINT32_TO_LE (conv
.i
[0]));
302 swfdec_bots_put_u32 (bots
, GUINT32_TO_LE (conv
.i
[1]));
307 swfdec_bit_sstorage (long x
)
311 return g_bit_storage (x
) + 1;
315 swfdec_bots_put_rect (SwfdecBots
*bots
, const SwfdecRect
*rect
)
320 g_return_if_fail (bots
!= NULL
);
321 g_return_if_fail (rect
!= NULL
);
327 req
= swfdec_bit_sstorage (x0
);
328 tmp
= swfdec_bit_sstorage (y0
);
329 req
= MAX (req
, tmp
);
330 tmp
= swfdec_bit_sstorage (x1
);
331 req
= MAX (req
, tmp
);
332 tmp
= swfdec_bit_sstorage (y1
);
333 req
= MAX (req
, tmp
);
334 swfdec_bots_syncbits (bots
);
335 swfdec_bots_put_bits (bots
, req
, 5);
336 swfdec_bots_put_sbits (bots
, x0
, req
);
337 swfdec_bots_put_sbits (bots
, x1
, req
);
338 swfdec_bots_put_sbits (bots
, y0
, req
);
339 swfdec_bots_put_sbits (bots
, y1
, req
);
340 swfdec_bots_syncbits (bots
);
344 swfdec_bots_put_matrix (SwfdecBots
*bots
, const cairo_matrix_t
*matrix
)
347 unsigned int xbits
, ybits
;
349 if (matrix
->xx
!= 1.0 || matrix
->yy
!= 1.0) {
350 swfdec_bots_put_bit (bots
, 1);
351 x
= SWFDEC_DOUBLE_TO_FIXED (matrix
->xx
);
352 y
= SWFDEC_DOUBLE_TO_FIXED (matrix
->yy
);
353 xbits
= swfdec_bit_sstorage (x
);
354 ybits
= swfdec_bit_sstorage (y
);
355 xbits
= MAX (xbits
, ybits
);
356 swfdec_bots_put_bits (bots
, xbits
, 5);
357 swfdec_bots_put_sbits (bots
, x
, xbits
);
358 swfdec_bots_put_sbits (bots
, y
, xbits
);
360 swfdec_bots_put_bit (bots
, 0);
362 if (matrix
->xy
!= 0.0 || matrix
->yx
!= 0.0) {
363 swfdec_bots_put_bit (bots
, 1);
364 x
= SWFDEC_DOUBLE_TO_FIXED (matrix
->yx
);
365 y
= SWFDEC_DOUBLE_TO_FIXED (matrix
->xy
);
366 xbits
= swfdec_bit_sstorage (x
);
367 ybits
= swfdec_bit_sstorage (y
);
368 xbits
= MAX (xbits
, ybits
);
369 swfdec_bots_put_bits (bots
, xbits
, 5);
370 swfdec_bots_put_sbits (bots
, x
, xbits
);
371 swfdec_bots_put_sbits (bots
, y
, xbits
);
373 swfdec_bots_put_bit (bots
, 0);
377 xbits
= swfdec_bit_sstorage (x
);
378 ybits
= swfdec_bit_sstorage (y
);
379 xbits
= MAX (xbits
, ybits
);
380 swfdec_bots_put_bits (bots
, xbits
, 5);
381 swfdec_bots_put_sbits (bots
, x
, xbits
);
382 swfdec_bots_put_sbits (bots
, y
, xbits
);
383 swfdec_bots_syncbits (bots
);
387 swfdec_bots_put_color_transform (SwfdecBots
*bots
, const SwfdecColorTransform
*trans
)
389 gboolean has_add
, has_mult
;
390 unsigned int n_bits
, tmp
;
392 has_mult
= trans
->ra
!= 256 || trans
->ga
!= 256 || trans
->ba
!= 256 || trans
->aa
!= 256;
393 has_add
= trans
->rb
!= 0 || trans
->gb
!= 0 || trans
->bb
!= 0 || trans
->ab
!= 0;
395 n_bits
= swfdec_bit_sstorage (trans
->ra
);
396 tmp
= swfdec_bit_sstorage (trans
->ga
);
397 n_bits
= MAX (tmp
, n_bits
);
398 tmp
= swfdec_bit_sstorage (trans
->ba
);
399 n_bits
= MAX (tmp
, n_bits
);
400 tmp
= swfdec_bit_sstorage (trans
->aa
);
401 n_bits
= MAX (tmp
, n_bits
);
406 tmp
= swfdec_bit_sstorage (trans
->rb
);
407 n_bits
= MAX (tmp
, n_bits
);
408 tmp
= swfdec_bit_sstorage (trans
->gb
);
409 n_bits
= MAX (tmp
, n_bits
);
410 tmp
= swfdec_bit_sstorage (trans
->bb
);
411 n_bits
= MAX (tmp
, n_bits
);
412 tmp
= swfdec_bit_sstorage (trans
->ab
);
413 n_bits
= MAX (tmp
, n_bits
);
415 if (n_bits
>= (1 << 4))
416 n_bits
= (1 << 4) - 1;
417 swfdec_bots_put_bit (bots
, has_add
);
418 swfdec_bots_put_bit (bots
, has_mult
);
419 swfdec_bots_put_bits (bots
, n_bits
, 4);
421 swfdec_bots_put_sbits (bots
, trans
->ra
, n_bits
);
422 swfdec_bots_put_sbits (bots
, trans
->ga
, n_bits
);
423 swfdec_bots_put_sbits (bots
, trans
->ba
, n_bits
);
424 swfdec_bots_put_sbits (bots
, trans
->aa
, n_bits
);
427 swfdec_bots_put_sbits (bots
, trans
->rb
, n_bits
);
428 swfdec_bots_put_sbits (bots
, trans
->gb
, n_bits
);
429 swfdec_bots_put_sbits (bots
, trans
->bb
, n_bits
);
430 swfdec_bots_put_sbits (bots
, trans
->ab
, n_bits
);
432 swfdec_bots_syncbits (bots
);
436 swfdec_bots_put_rgb (SwfdecBots
*bots
, SwfdecColor color
)
438 g_return_if_fail (bots
!= NULL
);
440 swfdec_bots_put_u8 (bots
, SWFDEC_COLOR_RED (color
));
441 swfdec_bots_put_u8 (bots
, SWFDEC_COLOR_GREEN (color
));
442 swfdec_bots_put_u8 (bots
, SWFDEC_COLOR_BLUE (color
));
446 swfdec_bots_put_rgba (SwfdecBots
*bots
, SwfdecColor color
)
448 g_return_if_fail (bots
!= NULL
);
450 swfdec_bots_put_u8 (bots
, SWFDEC_COLOR_RED (color
));
451 swfdec_bots_put_u8 (bots
, SWFDEC_COLOR_GREEN (color
));
452 swfdec_bots_put_u8 (bots
, SWFDEC_COLOR_BLUE (color
));
453 swfdec_bots_put_u8 (bots
, SWFDEC_COLOR_ALPHA (color
));