2 * Copyright (C) 2007-2008 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
24 #include "swfdec_filter.h"
26 #include "swfdec_blur_filter.h"
27 #include "swfdec_color_matrix_filter.h"
28 #include "swfdec_debug.h"
30 G_DEFINE_ABSTRACT_TYPE (SwfdecFilter
, swfdec_filter
, SWFDEC_TYPE_AS_RELAY
)
33 swfdec_filter_class_init (SwfdecFilterClass
*klass
)
38 swfdec_filter_init (SwfdecFilter
*array
)
43 swfdec_filter_clone (SwfdecFilter
*filter
)
46 SwfdecFilterClass
*klass
;
48 g_return_val_if_fail (SWFDEC_IS_FILTER (filter
), NULL
);
50 klass
= SWFDEC_FILTER_GET_CLASS (filter
);
51 clone
= g_object_new (G_OBJECT_CLASS_TYPE (klass
), "context",
52 swfdec_gc_object_get_context (filter
), NULL
);
53 klass
->clone (clone
, filter
);
59 swfdec_filter_apply (SwfdecFilter
*filter
, cairo_pattern_t
*pattern
,
60 double xscale
, double yscale
, const SwfdecRectangle
*rect
)
62 SwfdecFilterClass
*klass
;
65 g_return_val_if_fail (SWFDEC_IS_FILTER (filter
), NULL
);
66 g_return_val_if_fail (pattern
!= NULL
, NULL
);
67 g_return_val_if_fail (rect
!= NULL
, NULL
);
69 klass
= SWFDEC_FILTER_GET_CLASS (filter
);
70 g_assert (klass
->apply
);
72 ret
= klass
->apply (filter
, pattern
, xscale
, yscale
, rect
);
73 cairo_pattern_destroy (pattern
);
78 swfdec_filter_parse (SwfdecPlayer
*player
, SwfdecBits
*bits
)
80 GSList
*filters
= NULL
;
81 guint i
, n_filters
, filter_id
;
83 g_return_val_if_fail (SWFDEC_IS_PLAYER (player
), NULL
);
84 g_return_val_if_fail (bits
!= NULL
, NULL
);
86 n_filters
= swfdec_bits_get_u8 (bits
);
87 SWFDEC_LOG (" filters: %u", n_filters
);
88 for (i
= 0; i
< n_filters
&& swfdec_bits_left (bits
); i
++) {
89 filter_id
= swfdec_bits_get_u8 (bits
);
92 SWFDEC_WARNING (" drop shadow");
93 swfdec_bits_skip_bytes (bits
, 16);
97 SwfdecBlurFilter
*filter
;
99 filter
= g_object_new (SWFDEC_TYPE_BLUR_FILTER
,
100 "context", player
, NULL
);
101 SWFDEC_LOG (" blur");
102 filter
->x
= swfdec_bits_get_u32 (bits
) / 65536.0;
103 filter
->y
= swfdec_bits_get_u32 (bits
) / 65536.0;
104 filter
->quality
= swfdec_bits_getbits (bits
, 5);
105 SWFDEC_LOG (" x = %g", filter
->x
);
106 SWFDEC_LOG (" y = %g", filter
->x
);
107 SWFDEC_LOG (" quality = %u", filter
->quality
);
108 swfdec_bits_getbits (bits
, 3);
109 filters
= g_slist_prepend (filters
, filter
);
113 SWFDEC_WARNING (" glow");
114 swfdec_bits_skip_bytes (bits
, 15);
117 SWFDEC_WARNING (" bevel");
118 swfdec_bits_skip_bytes (bits
, 27);
123 n
= swfdec_bits_get_u8 (bits
);
124 SWFDEC_WARNING (" gradient glow");
125 swfdec_bits_skip_bytes (bits
, n
* 5 + 19);
131 x
= swfdec_bits_get_u8 (bits
);
132 y
= swfdec_bits_get_u8 (bits
);
133 SWFDEC_WARNING (" %u x %u convolution", x
, y
);
134 swfdec_bits_skip_bytes (bits
, (x
+ y
) * 4 + 13);
139 SwfdecColorMatrixFilter
*filter
;
142 filter
= g_object_new (SWFDEC_TYPE_COLOR_MATRIX_FILTER
,
143 "context", player
, NULL
);
144 SWFDEC_LOG (" color matrix");
145 for (j
= 0; j
< 20; j
++) {
146 filter
->matrix
[j
] = swfdec_bits_get_float (bits
);
148 filters
= g_slist_prepend (filters
, filter
);
154 n
= swfdec_bits_get_u8 (bits
);
155 SWFDEC_WARNING (" gradient bevel");
156 swfdec_bits_skip_bytes (bits
, n
* 5 + 19);
160 SWFDEC_ERROR ("unknown filter id %u", filter_id
);
165 filters
= g_slist_reverse (filters
);
170 swfdec_filter_skip (SwfdecBits
*bits
)
172 guint i
, n_filters
, filter_id
;
174 g_return_if_fail (bits
!= NULL
);
176 n_filters
= swfdec_bits_get_u8 (bits
);
177 for (i
= 0; i
< n_filters
&& swfdec_bits_left (bits
); i
++) {
178 filter_id
= swfdec_bits_get_u8 (bits
);
181 swfdec_bits_skip_bytes (bits
, 16);
184 swfdec_bits_skip_bytes (bits
, 9);
187 swfdec_bits_skip_bytes (bits
, 15);
190 swfdec_bits_skip_bytes (bits
, 27);
195 n
= swfdec_bits_get_u8 (bits
);
196 swfdec_bits_skip_bytes (bits
, n
* 5 + 19);
202 x
= swfdec_bits_get_u8 (bits
);
203 y
= swfdec_bits_get_u8 (bits
);
204 swfdec_bits_skip_bytes (bits
, (x
+ y
) * 4 + 13);
208 swfdec_bits_skip_bytes (bits
, 20 * 4);
213 n
= swfdec_bits_get_u8 (bits
);
214 swfdec_bits_skip_bytes (bits
, n
* 5 + 19);
218 SWFDEC_ERROR ("unknown filter id %u", filter_id
);
225 swfdec_filter_get_rectangle (SwfdecFilter
*filter
, SwfdecRectangle
*dest
,
226 double xscale
, double yscale
, const SwfdecRectangle
*source
)
228 SwfdecFilterClass
*klass
;
230 g_return_if_fail (SWFDEC_IS_FILTER (filter
));
231 g_return_if_fail (dest
!= NULL
);
232 g_return_if_fail (source
!= NULL
);
234 klass
= SWFDEC_FILTER_GET_CLASS (filter
);
235 klass
->get_rectangle (filter
, dest
, xscale
, yscale
, source
);