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
27 #include "swfdec_sprite.h"
28 #include "swfdec_debug.h"
29 #include "swfdec_movie.h"
30 #include "swfdec_player_internal.h"
31 #include "swfdec_script.h"
32 #include "swfdec_sound.h"
33 #include "swfdec_sprite_movie.h"
34 #include "swfdec_swf_decoder.h"
35 #include "swfdec_tag.h"
37 G_DEFINE_TYPE (SwfdecSprite
, swfdec_sprite
, SWFDEC_TYPE_GRAPHIC
)
40 swfdec_content_free (SwfdecContent
*content
)
42 g_free (content
->name
);
44 swfdec_event_list_free (content
->events
);
49 swfdec_sprite_dispose (GObject
*object
)
51 SwfdecSprite
* sprite
= SWFDEC_SPRITE (object
);
55 for (i
= 0; i
< sprite
->n_frames
; i
++) {
56 g_free (sprite
->frames
[i
].label
);
57 if (sprite
->frames
[i
].sound_head
)
58 g_object_unref (sprite
->frames
[i
].sound_head
);
59 if (sprite
->frames
[i
].sound_block
) {
60 swfdec_buffer_unref (sprite
->frames
[i
].sound_block
);
62 g_slist_foreach (sprite
->frames
[i
].sound
, (GFunc
) swfdec_sound_chunk_free
, NULL
);
63 g_slist_free (sprite
->frames
[i
].sound
);
65 g_free(sprite
->frames
);
67 for (i
= 0; i
< sprite
->actions
->len
; i
++) {
68 SwfdecSpriteAction
*cur
= &g_array_index (sprite
->actions
, SwfdecSpriteAction
, i
);
70 swfdec_buffer_unref (cur
->buffer
);
72 g_array_free (sprite
->actions
, TRUE
);
73 sprite
->actions
= NULL
;
74 if (sprite
->init_action
) {
75 swfdec_script_unref (sprite
->init_action
);
76 sprite
->init_action
= NULL
;
79 G_OBJECT_CLASS (swfdec_sprite_parent_class
)->dispose (object
);
83 swfdec_sprite_add_sound_chunk (SwfdecSprite
* sprite
, guint frame
,
84 SwfdecBuffer
* chunk
, int skip
, guint n_samples
)
86 g_assert (sprite
->frames
!= NULL
);
87 g_assert (chunk
!= NULL
|| n_samples
== 0);
89 if (sprite
->frames
[frame
].sound_head
== NULL
) {
90 SWFDEC_ERROR ("attempting to add a sound block without previous sound head");
91 swfdec_buffer_unref (chunk
);
94 if (sprite
->frames
[frame
].sound_block
) {
95 SWFDEC_ERROR ("attempting to add 2 sound blocks to one frame");
96 swfdec_buffer_unref (chunk
);
99 SWFDEC_LOG ("adding %u samples in %u bytes to frame %u", n_samples
,
100 chunk
? chunk
->length
: 0, frame
);
101 sprite
->frames
[frame
].sound_skip
= skip
;
102 sprite
->frames
[frame
].sound_block
= chunk
;
103 sprite
->frames
[frame
].sound_samples
= n_samples
*
104 swfdec_audio_format_get_granularity (sprite
->frames
[frame
].sound_head
->original_format
);
108 swfdec_sprite_add_action (SwfdecSprite
*sprite
, guint tag
, SwfdecBuffer
*buffer
)
110 SwfdecSpriteAction action
;
113 action
.buffer
= buffer
;
114 g_array_append_val (sprite
->actions
, action
);
118 swfdec_sprite_get_action (SwfdecSprite
*sprite
, guint n
, guint
*tag
, SwfdecBuffer
**buffer
)
120 SwfdecSpriteAction
*action
;
122 g_return_val_if_fail (SWFDEC_IS_SPRITE (sprite
), FALSE
);
123 g_return_val_if_fail (tag
!= NULL
, FALSE
);
124 g_return_val_if_fail (buffer
!= NULL
, FALSE
);
126 if (n
>= sprite
->actions
->len
)
128 action
= &g_array_index (sprite
->actions
, SwfdecSpriteAction
, n
);
130 *buffer
= action
->buffer
;
135 tag_func_set_background_color (SwfdecSwfDecoder
* s
, guint tag
)
137 SwfdecPlayer
*player
= SWFDEC_DECODER (s
)->player
;
138 SwfdecColor color
= swfdec_bits_get_color (&s
->b
);
140 if (player
->bgcolor_set
) {
141 /* only an INFO because it can be set by user, should be error if we check duplication of tag */
142 SWFDEC_INFO ("background color has been set to %X already, setting to %X ignored",
143 player
->bgcolor
, color
);
145 SWFDEC_LOG ("setting background color to %X", color
);
146 /* can't use swfdec_player_set_background_color() here, because the player is locked and doesn't emit signals */
147 player
->bgcolor
= color
;
148 player
->bgcolor_set
= TRUE
;
149 player
->invalid_extents
= player
->stage
;
150 g_array_set_size (player
->invalidations
, 1);
151 g_array_index (player
->invalidations
, SwfdecRectangle
, 0) = player
->stage
;
152 g_object_notify (G_OBJECT (player
), "background-color");
155 return SWFDEC_STATUS_OK
;
159 swfdec_content_new (int depth
)
161 SwfdecContent
*content
= g_new0 (SwfdecContent
, 1);
163 cairo_matrix_init_identity (&content
->transform
);
164 swfdec_color_transform_init_identity (&content
->color_transform
);
165 content
->depth
= depth
;
170 swfdec_sprite_create_movie (SwfdecGraphic
*graphic
, gsize
*size
)
172 SwfdecSpriteMovie
*ret
= g_object_new (SWFDEC_TYPE_SPRITE_MOVIE
, NULL
);
174 ret
->sprite
= SWFDEC_SPRITE (graphic
);
175 *size
= sizeof (SwfdecSpriteMovie
);
177 return SWFDEC_MOVIE (ret
);
181 swfdec_sprite_class_init (SwfdecSpriteClass
* g_class
)
183 GObjectClass
*object_class
= G_OBJECT_CLASS (g_class
);
184 SwfdecGraphicClass
*graphic_class
= SWFDEC_GRAPHIC_CLASS (g_class
);
186 object_class
->dispose
= swfdec_sprite_dispose
;
188 graphic_class
->create_movie
= swfdec_sprite_create_movie
;
192 swfdec_sprite_init (SwfdecSprite
* sprite
)
194 sprite
->actions
= g_array_new (FALSE
, FALSE
, sizeof (SwfdecSpriteAction
));
198 swfdec_sprite_set_n_frames (SwfdecSprite
*sprite
, guint n_frames
,
203 g_return_if_fail (SWFDEC_IS_SPRITE (sprite
));
207 sprite
->frames
= g_new0 (SwfdecSpriteFrame
, n_frames
);
208 sprite
->n_frames
= n_frames
;
211 for (i
= 0; i
< n_frames
; i
++) {
212 sprite
->frames
[i
].sound_samples
= 44100 * 256 / rate
;
216 SWFDEC_LOG ("n_frames = %d", sprite
->n_frames
);
220 swfdec_sprite_get_frame (SwfdecSprite
*sprite
, const char *label
)
224 g_return_val_if_fail (SWFDEC_IS_SPRITE (sprite
), -1);
225 g_return_val_if_fail (label
!= NULL
, -1);
227 for (i
= 0; i
< SWFDEC_SPRITE (sprite
)->n_frames
; i
++) {
228 SwfdecSpriteFrame
*frame
= &sprite
->frames
[i
];
229 if (frame
->label
== NULL
)
231 if (g_str_equal (frame
->label
, label
))