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_out.h"
29 swfdec_out_open (void)
31 SwfdecOut
*out
= g_new0 (SwfdecOut
, 1);
33 out
->data
= g_malloc (SWFDEC_OUT_INITIAL
);
35 out
->end
= out
->data
+ SWFDEC_OUT_INITIAL
;
41 swfdec_out_syncbits (SwfdecOut
*out
)
43 g_return_if_fail (out
!= NULL
);
52 swfdec_out_close (SwfdecOut
*out
)
56 g_return_val_if_fail (out
!= NULL
, NULL
);
58 swfdec_out_syncbits (out
);
60 buffer
= swfdec_buffer_new ();
61 buffer
->data
= out
->data
;
62 buffer
->length
= out
->ptr
- out
->data
;
70 swfdec_out_get_bits (SwfdecOut
*out
)
72 g_return_val_if_fail (out
!= NULL
, 0);
74 return (out
->ptr
- out
->data
) * 8 + out
->idx
;
78 swfdec_out_left (SwfdecOut
*out
)
80 g_return_val_if_fail (out
!= NULL
, 0);
82 return (out
->end
- out
->ptr
) * 8 - out
->idx
;
86 swfdec_out_ensure_bits (SwfdecOut
*out
, unsigned int bits
)
88 unsigned int current
, taken
, needed
;
90 g_return_if_fail (out
!= NULL
);
92 current
= swfdec_out_left (out
);
95 taken
= out
->ptr
- out
->data
;
96 needed
= (bits
- current
+ 7) / 8;
97 needed
+= SWFDEC_OUT_STEP
;
98 needed
-= needed
% SWFDEC_OUT_STEP
;
99 needed
+= out
->end
- out
->data
;
100 out
->data
= g_realloc (out
->data
, needed
);
101 out
->ptr
= out
->data
+ taken
;
102 out
->end
= out
->data
+ needed
;
106 swfdec_out_prepare_bytes (SwfdecOut
*out
, unsigned int bytes
)
108 g_return_if_fail (out
!= NULL
);
110 swfdec_out_syncbits (out
);
111 swfdec_out_ensure_bits (out
, bytes
* 8);
115 swfdec_out_put_data (SwfdecOut
*out
, const guint8
*data
, guint length
)
117 g_return_if_fail (out
!= NULL
);
119 swfdec_out_prepare_bytes (out
, length
);
120 memcpy (out
->ptr
, data
, length
);
125 swfdec_out_put_buffer (SwfdecOut
*out
, SwfdecBuffer
*buffer
)
127 g_return_if_fail (out
!= NULL
);
129 swfdec_out_prepare_bytes (out
, buffer
->length
);
130 memcpy (out
->ptr
, buffer
->data
, buffer
->length
);
131 out
->ptr
+= buffer
->length
;
135 swfdec_out_put_u8 (SwfdecOut
*out
, guint i
)
137 g_return_if_fail (i
<= G_MAXUINT8
);
139 swfdec_out_prepare_bytes (out
, 1);
145 swfdec_out_put_u16 (SwfdecOut
*out
, guint i
)
147 g_return_if_fail (i
<= G_MAXUINT16
);
149 swfdec_out_prepare_bytes (out
, 2);
150 *(guint16
*)out
->ptr
= GUINT16_TO_LE (i
);
155 swfdec_out_put_u32 (SwfdecOut
*out
, guint i
)
157 g_return_if_fail (i
<= G_MAXUINT32
);
159 swfdec_out_prepare_bytes (out
, 4);
160 *(guint32
*)out
->ptr
= GUINT32_TO_LE (i
);
165 swfdec_out_put_bit (SwfdecOut
*out
, gboolean bit
)
167 g_return_if_fail (out
!= NULL
);
169 swfdec_out_put_bits (out
, bit
? 1 : 0, 1);
173 swfdec_out_put_bits (SwfdecOut
*out
, guint bits
, guint n_bits
)
175 g_return_if_fail (out
!= NULL
);
177 swfdec_out_ensure_bits (out
, n_bits
);
179 /* FIXME: implement this less braindead */
181 guint bits_now
= MIN (n_bits
, 8 - out
->idx
);
182 guint value
= bits
>> (n_bits
- bits_now
);
184 /* clear data if necessary */
187 value
&= (1 << bits_now
) - 1;
188 value
<<= 8 - out
->idx
- bits_now
;
190 out
->idx
+= bits_now
;
191 g_assert (out
->idx
<= 8);
201 swfdec_out_put_sbits (SwfdecOut
*out
, int bits
, guint n_bits
)
203 g_return_if_fail (out
!= NULL
);
204 swfdec_out_put_bits (out
, bits
, n_bits
);
208 swfdec_out_put_string (SwfdecOut
*out
, const char *s
)
212 g_return_if_fail (out
!= NULL
);
213 g_return_if_fail (s
!= NULL
);
215 len
= strlen (s
) + 1;
217 swfdec_out_prepare_bytes (out
, len
);
218 memcpy (out
->ptr
, s
, len
);
223 swfdec_out_bits_required (guint x
)
235 swfdec_out_sbits_required (int x
)
239 return swfdec_out_bits_required (x
) + 1;
243 swfdec_out_put_rect (SwfdecOut
*out
, const SwfdecRect
*rect
)
248 g_return_if_fail (out
!= NULL
);
249 g_return_if_fail (rect
!= NULL
);
255 req
= swfdec_out_sbits_required (x0
);
256 tmp
= swfdec_out_sbits_required (y0
);
257 req
= MAX (req
, tmp
);
258 tmp
= swfdec_out_sbits_required (x1
);
259 req
= MAX (req
, tmp
);
260 tmp
= swfdec_out_sbits_required (y1
);
261 req
= MAX (req
, tmp
);
262 swfdec_out_syncbits (out
);
263 swfdec_out_put_bits (out
, req
, 5);
264 swfdec_out_put_sbits (out
, x0
, req
);
265 swfdec_out_put_sbits (out
, x1
, req
);
266 swfdec_out_put_sbits (out
, y0
, req
);
267 swfdec_out_put_sbits (out
, y1
, req
);
268 swfdec_out_syncbits (out
);
272 swfdec_out_put_matrix (SwfdecOut
*out
, const cairo_matrix_t
*matrix
)
275 unsigned int xbits
, ybits
;
277 if (matrix
->xx
!= 1.0 || matrix
->yy
!= 1.0) {
278 swfdec_out_put_bit (out
, 1);
279 x
= SWFDEC_DOUBLE_TO_FIXED (matrix
->xx
);
280 y
= SWFDEC_DOUBLE_TO_FIXED (matrix
->yy
);
281 xbits
= swfdec_out_sbits_required (x
);
282 ybits
= swfdec_out_sbits_required (y
);
283 xbits
= MAX (xbits
, ybits
);
284 swfdec_out_put_bits (out
, xbits
, 5);
285 swfdec_out_put_sbits (out
, x
, xbits
);
286 swfdec_out_put_sbits (out
, y
, xbits
);
288 swfdec_out_put_bit (out
, 0);
290 if (matrix
->xy
!= 0.0 || matrix
->yx
!= 0.0) {
291 swfdec_out_put_bit (out
, 1);
292 x
= SWFDEC_DOUBLE_TO_FIXED (matrix
->yx
);
293 y
= SWFDEC_DOUBLE_TO_FIXED (matrix
->xy
);
294 xbits
= swfdec_out_sbits_required (x
);
295 ybits
= swfdec_out_sbits_required (y
);
296 xbits
= MAX (xbits
, ybits
);
297 swfdec_out_put_bits (out
, xbits
, 5);
298 swfdec_out_put_sbits (out
, x
, xbits
);
299 swfdec_out_put_sbits (out
, y
, xbits
);
301 swfdec_out_put_bit (out
, 0);
305 xbits
= swfdec_out_sbits_required (x
);
306 ybits
= swfdec_out_sbits_required (y
);
307 xbits
= MAX (xbits
, ybits
);
308 swfdec_out_put_bits (out
, xbits
, 5);
309 swfdec_out_put_sbits (out
, x
, xbits
);
310 swfdec_out_put_sbits (out
, y
, xbits
);
311 swfdec_out_syncbits (out
);
315 swfdec_out_put_color_transform (SwfdecOut
*out
, const SwfdecColorTransform
*trans
)
317 gboolean has_add
, has_mult
;
318 unsigned int n_bits
, tmp
;
320 has_mult
= trans
->ra
!= 256 || trans
->ga
!= 256 || trans
->ba
!= 256 || trans
->aa
!= 256;
321 has_add
= trans
->rb
!= 0 || trans
->gb
!= 0 || trans
->bb
!= 0 || trans
->ab
!= 0;
323 n_bits
= swfdec_out_sbits_required (trans
->ra
);
324 tmp
= swfdec_out_sbits_required (trans
->ga
);
325 n_bits
= MAX (tmp
, n_bits
);
326 tmp
= swfdec_out_sbits_required (trans
->ba
);
327 n_bits
= MAX (tmp
, n_bits
);
328 tmp
= swfdec_out_sbits_required (trans
->aa
);
329 n_bits
= MAX (tmp
, n_bits
);
334 tmp
= swfdec_out_sbits_required (trans
->rb
);
335 n_bits
= MAX (tmp
, n_bits
);
336 tmp
= swfdec_out_sbits_required (trans
->gb
);
337 n_bits
= MAX (tmp
, n_bits
);
338 tmp
= swfdec_out_sbits_required (trans
->bb
);
339 n_bits
= MAX (tmp
, n_bits
);
340 tmp
= swfdec_out_sbits_required (trans
->ab
);
341 n_bits
= MAX (tmp
, n_bits
);
343 if (n_bits
>= (1 << 4))
344 n_bits
= (1 << 4) - 1;
345 swfdec_out_put_bit (out
, has_add
);
346 swfdec_out_put_bit (out
, has_mult
);
347 swfdec_out_put_bits (out
, n_bits
, 4);
349 swfdec_out_put_sbits (out
, trans
->ra
, n_bits
);
350 swfdec_out_put_sbits (out
, trans
->ga
, n_bits
);
351 swfdec_out_put_sbits (out
, trans
->ba
, n_bits
);
352 swfdec_out_put_sbits (out
, trans
->aa
, n_bits
);
355 swfdec_out_put_sbits (out
, trans
->rb
, n_bits
);
356 swfdec_out_put_sbits (out
, trans
->gb
, n_bits
);
357 swfdec_out_put_sbits (out
, trans
->bb
, n_bits
);
358 swfdec_out_put_sbits (out
, trans
->ab
, n_bits
);
360 swfdec_out_syncbits (out
);
364 swfdec_out_put_rgb (SwfdecOut
*out
, SwfdecColor color
)
366 g_return_if_fail (out
!= NULL
);
368 swfdec_out_put_u8 (out
, SWFDEC_COLOR_R (color
));
369 swfdec_out_put_u8 (out
, SWFDEC_COLOR_G (color
));
370 swfdec_out_put_u8 (out
, SWFDEC_COLOR_B (color
));
374 swfdec_out_put_rgba (SwfdecOut
*out
, SwfdecColor color
)
376 g_return_if_fail (out
!= NULL
);
378 swfdec_out_put_u8 (out
, SWFDEC_COLOR_R (color
));
379 swfdec_out_put_u8 (out
, SWFDEC_COLOR_G (color
));
380 swfdec_out_put_u8 (out
, SWFDEC_COLOR_B (color
));
381 swfdec_out_put_u8 (out
, SWFDEC_COLOR_A (color
));