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_sprite_dispose (GObject
*object
)
42 SwfdecSprite
* sprite
= SWFDEC_SPRITE (object
);
46 for (i
= 0; i
< sprite
->n_frames
; i
++) {
47 g_free (sprite
->frames
[i
].label
);
48 if (sprite
->frames
[i
].sound_head
)
49 g_object_unref (sprite
->frames
[i
].sound_head
);
50 if (sprite
->frames
[i
].sound_block
) {
51 swfdec_buffer_unref (sprite
->frames
[i
].sound_block
);
53 g_slist_foreach (sprite
->frames
[i
].sound
, (GFunc
) swfdec_sound_chunk_free
, NULL
);
54 g_slist_free (sprite
->frames
[i
].sound
);
56 g_free(sprite
->frames
);
58 for (i
= 0; i
< sprite
->actions
->len
; i
++) {
59 SwfdecSpriteAction
*cur
= &g_array_index (sprite
->actions
, SwfdecSpriteAction
, i
);
61 swfdec_buffer_unref (cur
->buffer
);
63 g_array_free (sprite
->actions
, TRUE
);
64 sprite
->actions
= NULL
;
65 if (sprite
->init_action
) {
66 swfdec_script_unref (sprite
->init_action
);
67 sprite
->init_action
= NULL
;
70 G_OBJECT_CLASS (swfdec_sprite_parent_class
)->dispose (object
);
74 swfdec_sprite_add_sound_chunk (SwfdecSprite
* sprite
, guint frame
,
75 SwfdecBuffer
* chunk
, int skip
, guint n_samples
)
77 g_assert (sprite
->frames
!= NULL
);
78 g_assert (chunk
!= NULL
|| n_samples
== 0);
80 if (sprite
->frames
[frame
].sound_head
== NULL
) {
81 SWFDEC_ERROR ("attempting to add a sound block without previous sound head");
82 swfdec_buffer_unref (chunk
);
85 if (sprite
->frames
[frame
].sound_block
) {
86 SWFDEC_ERROR ("attempting to add 2 sound blocks to one frame");
87 swfdec_buffer_unref (chunk
);
90 SWFDEC_LOG ("adding %u samples in %u bytes to frame %u", n_samples
,
91 chunk
? chunk
->length
: 0, frame
);
92 sprite
->frames
[frame
].sound_skip
= skip
;
93 sprite
->frames
[frame
].sound_block
= chunk
;
94 sprite
->frames
[frame
].sound_samples
= n_samples
*
95 swfdec_audio_format_get_granularity (sprite
->frames
[frame
].sound_head
->format
);
99 swfdec_sprite_add_action (SwfdecSprite
*sprite
, guint tag
, SwfdecBuffer
*buffer
)
101 SwfdecSpriteAction action
;
104 action
.buffer
= buffer
;
105 g_array_append_val (sprite
->actions
, action
);
109 swfdec_sprite_get_action (SwfdecSprite
*sprite
, guint n
, guint
*tag
, SwfdecBuffer
**buffer
)
111 SwfdecSpriteAction
*action
;
113 g_return_val_if_fail (SWFDEC_IS_SPRITE (sprite
), FALSE
);
114 g_return_val_if_fail (tag
!= NULL
, FALSE
);
115 g_return_val_if_fail (buffer
!= NULL
, FALSE
);
117 if (n
>= sprite
->actions
->len
)
119 action
= &g_array_index (sprite
->actions
, SwfdecSpriteAction
, n
);
121 *buffer
= action
->buffer
;
126 tag_func_set_background_color (SwfdecSwfDecoder
* s
, guint tag
)
128 SwfdecPlayer
*player
= SWFDEC_DECODER (s
)->player
;
129 SwfdecPlayerPrivate
*priv
= player
->priv
;
130 SwfdecColor color
= swfdec_bits_get_color (&s
->b
);
132 if (priv
->bgcolor_set
) {
133 /* only an INFO because it can be set by user, should be error if we check duplication of tag */
134 SWFDEC_INFO ("background color has been set to %X already, setting to %X ignored",
135 priv
->bgcolor
, color
);
137 SWFDEC_LOG ("setting background color to %X", color
);
138 /* can't use swfdec_player_set_background_color() here, because the player is locked and doesn't emit signals */
139 priv
->bgcolor
= color
;
140 priv
->bgcolor_set
= TRUE
;
141 priv
->invalid_extents
= priv
->stage
;
142 g_array_set_size (priv
->invalidations
, 1);
143 g_array_index (priv
->invalidations
, SwfdecRectangle
, 0) = priv
->stage
;
144 g_object_notify (G_OBJECT (player
), "background-color");
147 return SWFDEC_STATUS_OK
;
151 swfdec_sprite_create_movie (SwfdecGraphic
*graphic
, gsize
*size
)
153 SwfdecSpriteMovie
*ret
= g_object_new (SWFDEC_TYPE_SPRITE_MOVIE
, NULL
);
155 ret
->sprite
= SWFDEC_SPRITE (graphic
);
156 ret
->n_frames
= ret
->sprite
->n_frames
;
157 *size
= sizeof (SwfdecSpriteMovie
);
159 return SWFDEC_MOVIE (ret
);
163 swfdec_sprite_class_init (SwfdecSpriteClass
* g_class
)
165 GObjectClass
*object_class
= G_OBJECT_CLASS (g_class
);
166 SwfdecGraphicClass
*graphic_class
= SWFDEC_GRAPHIC_CLASS (g_class
);
168 object_class
->dispose
= swfdec_sprite_dispose
;
170 graphic_class
->create_movie
= swfdec_sprite_create_movie
;
174 swfdec_sprite_init (SwfdecSprite
* sprite
)
176 sprite
->actions
= g_array_new (FALSE
, FALSE
, sizeof (SwfdecSpriteAction
));
180 swfdec_sprite_set_n_frames (SwfdecSprite
*sprite
, guint n_frames
,
185 g_return_if_fail (SWFDEC_IS_SPRITE (sprite
));
187 sprite
->frames
= g_new0 (SwfdecSpriteFrame
, n_frames
);
188 sprite
->n_frames
= n_frames
;
191 for (i
= 0; i
< n_frames
; i
++) {
192 sprite
->frames
[i
].sound_samples
= 44100 * 256 / rate
;
197 SWFDEC_LOG ("n_frames = %d", sprite
->n_frames
);
201 swfdec_sprite_get_frame (SwfdecSprite
*sprite
, const char *label
)
205 g_return_val_if_fail (SWFDEC_IS_SPRITE (sprite
), -1);
206 g_return_val_if_fail (label
!= NULL
, -1);
208 for (i
= 0; i
< SWFDEC_SPRITE (sprite
)->n_frames
; i
++) {
209 SwfdecSpriteFrame
*frame
= &sprite
->frames
[i
];
210 if (frame
->label
== NULL
)
212 if (g_str_equal (frame
->label
, label
))