1 /*
2     Ming, an SWF output library
3     Copyright (C) 2008 Klaus Rechert
4 
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9 
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Lesser General Public License for more details.
14 
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19 
20 /* $Id$ */
21 
22 #ifndef __C2MAN__
23 #include <stdlib.h>
24 #include <string.h>
25 #endif
26 
27 #include "gradient.h"
28 #include "output.h"
29 #include "filter.h"
30 #include "error.h"
31 
32 #include "libming.h"
33 
34 
35 struct Shadow_s
36 {
37 	float	angle;
38 	float	distance;
39 	float 	strength;
40 };
41 
42 
43 /*
44  * create a new SWFShadow (contructor)
45  * This Function creates a new SWFShadow object. Only useful for creating
46  * SWFFilter objects.
47  */
48 SWFShadow
newSWFShadow(float angle,float distance,float strength)49 newSWFShadow(float angle /* angle in radians */,
50              float distance /* distance in px*/,
51              float strength /* strength */)
52 {
53 	SWFShadow shadow = (SWFShadow)malloc(sizeof(struct Shadow_s));
54 
55 	shadow->angle = angle;
56 	shadow->distance = distance;
57 	shadow->strength = strength;
58 
59 	return shadow;
60 }
61 
destroySWFShadow(SWFShadow s)62 void destroySWFShadow(SWFShadow s)
63 {
64 	free(s);
65 }
66 
67 struct Blur_s
68 {
69 	float 	blurX;
70 	float 	blurY;
71 	int 	passes;
72 };
73 
74 
75 /*
76  * create a new SWFBlur
77  * This function creates a new SWFBlur object. Only useful for creating
78  * SWFFilter objects
79  */
80 SWFBlur
newSWFBlur(float blurX,float blurY,int passes)81 newSWFBlur(float blurX /* horiz. blur amount */,
82            float blurY /* vert. blur amount */,
83            int passes /* number of passes. shoub be <= 3 */)
84 {
85 	SWFBlur blur = (SWFBlur)malloc(sizeof(struct Blur_s));
86 
87 	blur->blurX = blurX;
88 	blur->blurY = blurY;
89 	blur->passes = passes;
90 
91 	return blur;
92 }
93 
destroySWFBlur(SWFBlur b)94 void destroySWFBlur(SWFBlur b)
95 {
96 	free(b);
97 }
98 
99 struct BlurFilter
100 {
101 	SWFBlur blur;
102 };
103 
104 struct DropShadowFilter
105 {
106 	SWFColor		color;
107 	SWFBlur 		blur;
108 	SWFShadow		shadow;
109 	int 			flags;
110 };
111 
112 struct GlowFilter
113 {
114 	SWFColor	color;
115 	SWFBlur		blur;
116 	float 		strength;
117 	int 		flags;
118 };
119 
120 struct BevelFilter
121 {
122 	SWFColor	shadowColor;
123 	SWFColor	highlightColor;
124 	SWFBlur		blur;
125 	SWFShadow	shadow;
126 	int 		flags;
127 };
128 
129 struct GradientGlowFilter
130 {
131 	SWFGradient	gradient;
132 	SWFBlur		blur;
133 	SWFShadow	shadow;
134 	int 		flags;
135 };
136 
137 struct GradientBevelFilter
138 {
139 	SWFGradient	gradient;
140 	SWFBlur	 	blur;
141 	SWFShadow	shadow;
142 	int 		flags;
143 };
144 
145 
146 struct FilterMatrix_s
147 {
148 	int cols;
149 	int rows;
150 	float *values;
151 };
152 
153 /*
154  * create a new FilterMatrix (constructor)
155  * This function creates a new SFWFilterMatrix. Only useful
156  * for creating SWFFilter objects.
157  */
158 SWFFilterMatrix
newSWFFilterMatrix(int cols,int rows,float * vals)159 newSWFFilterMatrix(int cols /* number of cols */,
160                    int rows /* number of rows */,
161                    float *vals /* vals[cols * rows]. Will be copied */)
162 {
163 	SWFFilterMatrix matrix;
164 
165 	if(cols <= 0 || rows <= 0)
166 		return NULL;
167 
168 	matrix = (SWFFilterMatrix)malloc(sizeof(struct FilterMatrix_s));
169 
170 	matrix->cols = cols;
171 	matrix->rows = rows;
172 
173 	matrix->values = (float *)malloc(cols * rows * sizeof(float));
174 	memcpy(matrix->values, vals, cols * rows * sizeof(float));
175 
176 	return matrix;
177 }
178 
destroySWFFilterMatrix(SWFFilterMatrix m)179 void destroySWFFilterMatrix(SWFFilterMatrix m)
180 {
181 	if(m == NULL)
182 		return;
183 
184 	free(m->values);
185 	free(m);
186 }
187 
188 struct ConvolutionFilter
189 {
190 	SWFFilterMatrix matrix;
191 	float 		divisor;
192 	float 		bias;
193 	SWFColor	color;
194 	int		flags;
195 };
196 
197 
198 struct ColorMatrixFilter
199 {
200 	SWFFilterMatrix matrix;
201 };
202 
203 struct SWFFilter_s
204 {
205 	int id;
206 	union {
207 		struct DropShadowFilter 	dropShadow;
208 		struct BlurFilter		blur;
209 		struct GlowFilter		glow;
210 		struct BevelFilter		bevel;
211 		struct GradientGlowFilter	gradientGlow;
212 		struct ConvolutionFilter	convolution;
213 		struct ColorMatrixFilter	colorMatrix;
214 		struct GradientBevelFilter	gradientBevel;
215 	} filter;
216 };
217 
writeDropShadowFilter(SWFOutput out,struct DropShadowFilter * filter)218 static void writeDropShadowFilter(SWFOutput out, struct DropShadowFilter *filter)
219 {
220 	int flags = FILTER_MODE_COMPOSITE;
221 
222 	SWFOutput_writeUInt8(out, filter->color.red);
223 	SWFOutput_writeUInt8(out, filter->color.green);
224 	SWFOutput_writeUInt8(out, filter->color.blue);
225 	SWFOutput_writeUInt8(out, filter->color.alpha);
226 
227 	SWFOutput_writeFixed(out, filter->blur->blurX);
228 	SWFOutput_writeFixed(out, filter->blur->blurY);
229 
230 	SWFOutput_writeFixed(out, filter->shadow->angle);
231 	SWFOutput_writeFixed(out, filter->shadow->distance);
232 	SWFOutput_writeFixed8(out, filter->shadow->strength);
233 
234 	flags |= filter->flags;
235 	flags |= (0x1F & filter->blur->passes);
236 	SWFOutput_writeUInt8(out, flags);
237 }
238 
writeBlurFilter(SWFOutput out,struct BlurFilter * filter)239 static void writeBlurFilter(SWFOutput out, struct BlurFilter *filter)
240 {
241 	int flags = 0;
242 
243 	SWFOutput_writeFixed(out, filter->blur->blurX);
244 	SWFOutput_writeFixed(out, filter->blur->blurY);
245 
246 	flags = 0xff & (filter->blur->passes << 3);
247 	SWFOutput_writeUInt8(out, flags);
248 }
249 
writeGlowFilter(SWFOutput out,struct GlowFilter * filter)250 static void writeGlowFilter(SWFOutput out, struct GlowFilter *filter)
251 {
252 	int flags = FILTER_MODE_COMPOSITE;
253 
254 	SWFOutput_writeUInt8(out, filter->color.red);
255 	SWFOutput_writeUInt8(out, filter->color.green);
256 	SWFOutput_writeUInt8(out, filter->color.blue);
257 	SWFOutput_writeUInt8(out, filter->color.alpha);
258 
259 	SWFOutput_writeFixed(out, filter->blur->blurX);
260 	SWFOutput_writeFixed(out, filter->blur->blurY);
261 
262 	SWFOutput_writeFixed8(out, filter->strength);
263 	flags |= filter->flags;
264 	flags |= (0x1F & filter->blur->passes);
265 	SWFOutput_writeUInt8(out, flags);
266 }
267 
writeBevelFilter(SWFOutput out,struct BevelFilter * filter)268 static void writeBevelFilter(SWFOutput out, struct BevelFilter *filter)
269 {
270 	int flags = FILTER_MODE_COMPOSITE;
271 
272 	SWFOutput_writeUInt8(out, filter->shadowColor.red);
273 	SWFOutput_writeUInt8(out, filter->shadowColor.green);
274 	SWFOutput_writeUInt8(out, filter->shadowColor.blue);
275 	SWFOutput_writeUInt8(out, filter->shadowColor.alpha);
276 
277 	SWFOutput_writeUInt8(out, filter->highlightColor.red);
278 	SWFOutput_writeUInt8(out, filter->highlightColor.green);
279 	SWFOutput_writeUInt8(out, filter->highlightColor.blue);
280 	SWFOutput_writeUInt8(out, filter->highlightColor.alpha);
281 
282 	SWFOutput_writeFixed(out, filter->blur->blurX);
283 	SWFOutput_writeFixed(out, filter->blur->blurY);
284 
285 	SWFOutput_writeFixed(out, filter->shadow->angle);
286 	SWFOutput_writeFixed(out, filter->shadow->distance);
287 	SWFOutput_writeFixed8(out, filter->shadow->strength);
288 
289 	flags |= filter->flags;
290 	flags |= (0xF & filter->blur->passes);
291 	SWFOutput_writeUInt8(out, flags);
292 }
293 
writeGradientGlowFilter(SWFOutput out,struct GradientGlowFilter * filter)294 static void writeGradientGlowFilter(SWFOutput out, struct GradientGlowFilter *filter)
295 {
296 	int flags = FILTER_MODE_COMPOSITE;
297 
298 	SWFOutput_writeGradientAsFilter(out, filter->gradient);
299 
300 	SWFOutput_writeFixed(out, filter->blur->blurX);
301 	SWFOutput_writeFixed(out, filter->blur->blurY);
302 
303 	SWFOutput_writeFixed(out, filter->shadow->angle);
304 	SWFOutput_writeFixed(out, filter->shadow->distance);
305 	SWFOutput_writeFixed8(out, filter->shadow->strength);
306 
307 	flags |= filter->flags;
308 	flags |= (0xF & filter->blur->passes);
309 	SWFOutput_writeUInt8(out, flags);
310 }
311 
writeConvolutionFilter(SWFOutput out,struct ConvolutionFilter * filter)312 static void writeConvolutionFilter(SWFOutput out, struct ConvolutionFilter *filter)
313 {
314 	int i;
315 
316 	SWFOutput_writeUInt8(out, filter->matrix->cols);
317 	SWFOutput_writeUInt8(out, filter->matrix->rows);
318 
319 	SWFOutput_writeFloat(out, filter->divisor);
320 	SWFOutput_writeFloat(out, filter->bias);
321 
322 	for(i = 0; i < filter->matrix->cols * filter->matrix->rows; i++)
323 		SWFOutput_writeFloat(out, filter->matrix->values[i]);
324 
325 	SWFOutput_writeUInt8(out, filter->color.red);
326 	SWFOutput_writeUInt8(out, filter->color.green);
327 	SWFOutput_writeUInt8(out, filter->color.blue);
328 	SWFOutput_writeUInt8(out, filter->color.alpha);
329 
330 	SWFOutput_writeUInt8(out, filter->flags);
331 }
332 
writeColorMatrixFilter(SWFOutput out,struct ColorMatrixFilter * filter)333 static void writeColorMatrixFilter(SWFOutput out, struct ColorMatrixFilter *filter)
334 {
335 	int i;
336 
337 	for(i = 0; i < filter->matrix->rows * filter->matrix->cols; i++)
338 		SWFOutput_writeFloat(out, filter->matrix->values[i]);
339 }
340 
writeGradientBevelFilter(SWFOutput out,struct GradientBevelFilter * filter)341 static void writeGradientBevelFilter(SWFOutput out, struct GradientBevelFilter *filter)
342 {
343 	int flags = FILTER_MODE_COMPOSITE;
344 
345 	SWFOutput_writeGradientAsFilter(out, filter->gradient);
346 
347 	SWFOutput_writeFixed(out, filter->blur->blurX);
348 	SWFOutput_writeFixed(out, filter->blur->blurY);
349 
350 	SWFOutput_writeFixed(out, filter->shadow->angle);
351 	SWFOutput_writeFixed(out, filter->shadow->distance);
352 	SWFOutput_writeFixed8(out, filter->shadow->strength);
353 
354 	flags |= filter->flags;
355 	flags |= (0xF & filter->blur->passes);
356 	SWFOutput_writeUInt8(out, flags);
357 }
358 
359 void
SWFOutput_writeSWFFilter(SWFOutput out,SWFFilter filter)360 SWFOutput_writeSWFFilter(SWFOutput out, SWFFilter filter)
361 {
362 	if(out == NULL || filter == NULL)
363 		return;
364 
365 	SWFOutput_writeUInt8(out, filter->id);
366 	switch(filter->id)
367 	{
368 		case SWFFILTER_TYPE_DROPSHADOW:
369 			writeDropShadowFilter(out, &filter->filter.dropShadow);
370 			break;
371 		case SWFFILTER_TYPE_BLUR:
372 			writeBlurFilter(out, &filter->filter.blur);
373 			break;
374 		case SWFFILTER_TYPE_GLOW:
375 			writeGlowFilter(out, &filter->filter.glow);
376 			break;
377 		case SWFFILTER_TYPE_BEVEL:
378 			writeBevelFilter(out, &filter->filter.bevel);
379 			break;
380 		case SWFFILTER_TYPE_GRADIENTGLOW:
381 			writeGradientGlowFilter(out, &filter->filter.gradientGlow);
382 			break;
383 		case SWFFILTER_TYPE_CONVOLUTION:
384 			writeConvolutionFilter(out, &filter->filter.convolution);
385 			break;
386 		case SWFFILTER_TYPE_COLORMATRIX:
387 			writeColorMatrixFilter(out, &filter->filter.colorMatrix);
388 			break;
389 		case SWFFILTER_TYPE_GRADIENTBEVEL:
390 			writeGradientBevelFilter(out, &filter->filter.gradientBevel);
391 			break;
392 		default:
393 			SWF_error("destroySWFFilter: invalid filter\n");
394 	}
395 
396 }
397 
398 void
destroySWFFilter(SWFFilter filter)399 destroySWFFilter(SWFFilter filter)
400 {
401 	if(filter == NULL)
402 		return;
403 
404 	switch(filter->id)
405 	{
406 		case SWFFILTER_TYPE_DROPSHADOW:
407 			// destroyDropShadowFilter(&filter->filter.dropShadow);
408 			break;
409 		case SWFFILTER_TYPE_BLUR:
410 			// destroyBlurFilter(&filter->filter.blur);
411 			break;
412 		case SWFFILTER_TYPE_GLOW:
413 			// destroyGlowFilter(&filter->filter.glow);
414 			break;
415 		case SWFFILTER_TYPE_BEVEL:
416 			//destroyBevelFilter(&filter->filter.bevel);
417 			break;
418 		case SWFFILTER_TYPE_GRADIENTGLOW:
419 			// destroyGradientGlowFilter(&filter->filter.gradientGlow);
420 			break;
421 		case SWFFILTER_TYPE_CONVOLUTION:
422 			// destroyConvolutionFilter(&filter->filter.convolution);
423 			break;
424 		case SWFFILTER_TYPE_COLORMATRIX:
425 			// destroyColorMatrixFilter(&filter->filter.colorMatrix);
426 			break;
427 		case SWFFILTER_TYPE_GRADIENTBEVEL:
428 			// destroyGradientBevelFilter(&filter->filter.gradientBevel);
429 			break;
430 		default:
431 			SWF_error("destroySWFFilter: invalid filter\n");
432 	}
433 	free(filter);
434 }
435 
436 /*
437  * creates a new ColormatrixFilter
438  * Matrix has to be 5 x 4
439  * [r0 ... r4]
440  * [g0 ... g4]
441  * [b0 ... b4]
442  * [a0 ... a4]
443  */
444 SWFFilter
newColorMatrixFilter(SWFFilterMatrix matrix)445 newColorMatrixFilter(SWFFilterMatrix matrix /* matrix */)
446 {
447 	SWFFilter filter;
448 
449 	if(matrix == NULL)
450 		return NULL;
451 
452 	if(matrix->rows != 4 || matrix->cols != 5)
453 	{
454 		SWF_warn("newColorMatrixFilter: color matrix has to be 5x4\n");
455 		return NULL;
456 	}
457 
458 	filter = (SWFFilter)malloc(sizeof(struct SWFFilter_s));
459 	filter->id = SWFFILTER_TYPE_COLORMATRIX;
460 
461 	filter->filter.colorMatrix.matrix = matrix;
462 
463 	return filter;
464 }
465 
466 /*
467  * creates a new ConvolutionFilter
468  */
469 SWFFilter
newConvolutionFilter(SWFFilterMatrix matrix,float divisor,float bias,SWFColor color,int flags)470 newConvolutionFilter(SWFFilterMatrix matrix /* matrix */,
471                      float divisor /* divisor applied to matrix */,
472                      float bias /* matrix bias */,
473                      SWFColor color /* default color */,
474                      int flags /* FILTER_FLAG_CLAMP , FILTER_FLAG_PRESERVE_ALPHA */)
475 {
476 	SWFFilter filter;
477 	struct ConvolutionFilter *convolution;
478 
479 	if(matrix == NULL)
480 		return NULL;
481 
482 	filter = (SWFFilter)malloc(sizeof(struct SWFFilter_s));
483 	filter->id = SWFFILTER_TYPE_CONVOLUTION;
484 
485 	convolution = &filter->filter.convolution;
486 
487 	convolution->matrix = matrix;
488 	convolution->divisor = divisor;
489 	convolution->bias = bias;
490 	convolution->color = color;
491 	convolution->flags = flags;
492 
493 	return filter;
494 }
495 
496 
497 
498 /*
499  * create a GradientBevelFilter
500  * This functions creates a gradient bevel filter. Extends BevelFilter by
501  * using a gradient instead of a simple color
502  */
503 SWFFilter
newGradientBevelFilter(SWFGradient gradient,SWFBlur blur,SWFShadow shadow,int flags)504 newGradientBevelFilter(SWFGradient gradient /* gradient */,
505                        SWFBlur blur /* blur */,
506                        SWFShadow shadow /* shadow */,
507                        int flags /* FILTER_MODE_INNER,  FILTER_MODE_KO, FILTER_MODE_ONTOP */)
508 {
509 	SWFFilter filter;
510 	struct GradientBevelFilter *gBevel;
511 
512 	if(gradient == NULL || blur == NULL)
513 		return NULL;
514 
515 	filter = (SWFFilter)malloc(sizeof(struct SWFFilter_s));
516 	filter->id = SWFFILTER_TYPE_GRADIENTBEVEL;
517 
518 	gBevel = &filter->filter.gradientBevel;
519 
520 	gBevel->gradient = gradient;
521 	gBevel->blur = blur;
522 	gBevel->shadow = shadow;
523 	gBevel->flags = flags;
524 
525 	return filter;
526 }
527 
528 /*
529  * creates a GardientGlowFilter
530  * This functions creates a gradient glow filter. Extends GlowFilter by
531  * using a gradient instead of a simple color
532  */
533 SWFFilter
newGradientGlowFilter(SWFGradient gradient,SWFBlur blur,SWFShadow shadow,int flags)534 newGradientGlowFilter(SWFGradient gradient /* gradient */,
535                       SWFBlur blur /* blur */,
536                       SWFShadow shadow /* shadow */,
537                       int flags /* FILTER_MODE_INNER,  FILTER_MODE_KO, FILTER_MODE_ONTOP */)
538 {
539 	SWFFilter filter;
540 	struct GradientGlowFilter *gGlow;
541 
542 	if(gradient == NULL || blur == NULL)
543 		return NULL;
544 
545 	filter = (SWFFilter)malloc(sizeof(struct SWFFilter_s));
546 	filter->id = SWFFILTER_TYPE_GRADIENTGLOW;
547 
548 	gGlow = &filter->filter.gradientGlow;
549 
550 	gGlow->gradient = gradient;
551 	gGlow->blur = blur;
552 	gGlow->shadow = shadow;
553 	gGlow->flags = flags;
554 
555 	return filter;
556 }
557 
558 /*
559  * creates a BevelFilter
560  * This functions creates a bevel filter. Creates a smooth bevel
561  */
562 SWFFilter
newBevelFilter(SWFColor shadowColor,SWFColor highlightColor,SWFBlur blur,SWFShadow shadow,int flags)563 newBevelFilter(SWFColor shadowColor /* shadow color */,
564                SWFColor highlightColor /* highlight color */,
565                SWFBlur blur /* blur */,
566                SWFShadow shadow /* shadow */,
567                int flags /* FILTER_MODE_INNER,  FILTER_MODE_KO, FILTER_MODE_ONTOP */)
568 {
569 	SWFFilter filter;
570 	struct BevelFilter *bevel;
571 
572 	if(blur == NULL || shadow == NULL)
573 		return NULL;
574 
575 	filter = (SWFFilter)malloc(sizeof(struct SWFFilter_s));
576 	filter->id = SWFFILTER_TYPE_BEVEL;
577 
578 	bevel = &filter->filter.bevel;
579 
580 	bevel->shadowColor = shadowColor;
581 	bevel->highlightColor = highlightColor;
582 	bevel->blur = blur;
583 	bevel->shadow = shadow;
584 	bevel->flags = flags;
585 
586 	return filter;
587 }
588 
589 /*
590  * creates a GlowFilter
591  * This functions creates a glow filter.
592  */
593 SWFFilter
newGlowFilter(SWFColor color,SWFBlur blur,float strength,int flags)594 newGlowFilter(SWFColor color /* color of shadow */,
595               SWFBlur blur /* blur */,
596               float strength /* strength */,
597               int flags /* FILTER_MODE_INNER,  FILTER_MODE_KO */)
598 {
599 	SWFFilter filter;
600 	struct GlowFilter *glow;
601 
602 	if(blur == NULL)
603 		return NULL;
604 
605 	filter = (SWFFilter)malloc(sizeof(struct SWFFilter_s));
606 	filter->id = SWFFILTER_TYPE_GLOW;
607 
608 	glow = &filter->filter.glow;
609 
610 	glow->color = color;
611 	glow->blur = blur;
612 	glow->strength = strength;
613 	glow->flags = flags;
614 
615 	return filter;
616 }
617 
618 /*
619  * creates a BlurFilter
620  * This functions creates a blur filter.
621  */
622 SWFFilter
newBlurFilter(SWFBlur blur)623 newBlurFilter(SWFBlur blur /* blur */)
624 {
625 	SWFFilter filter;
626 	struct BlurFilter *b;
627 	if(blur == NULL)
628 		return NULL;
629 
630 	filter = (SWFFilter)malloc(sizeof(struct SWFFilter_s));
631 	filter->id = SWFFILTER_TYPE_BLUR;
632 	b = &filter->filter.blur;
633 	b->blur = blur;
634 
635 	return filter;
636 }
637 
638 /*
639  * creates a DropShadowFilter
640  * This functions creates a drop shadow filter filter.
641  */
642 SWFFilter
newDropShadowFilter(SWFColor color,SWFBlur blur,SWFShadow shadow,int flags)643 newDropShadowFilter(SWFColor color /* color of shadow */,
644                     SWFBlur blur /* blur */,
645                     SWFShadow shadow /* shadow */,
646                     int flags /* FILTER_MODE_INNER,  FILTER_MODE_KO */)
647 {
648 	struct DropShadowFilter *dropShadow;
649 	SWFFilter filter;
650 
651 	if(blur == NULL || shadow == NULL)
652 		return NULL;
653 
654 	filter = (SWFFilter)malloc(sizeof(struct SWFFilter_s));
655 	filter->id = SWFFILTER_TYPE_DROPSHADOW;
656 
657 	dropShadow = &filter->filter.dropShadow;
658 	dropShadow->color = color;
659 	dropShadow->blur = blur;
660 	dropShadow->shadow = shadow;
661 	dropShadow->flags = flags;
662 
663 	return filter;
664 }
665 
newSWFFilterList()666 SWFFilterList newSWFFilterList()
667 {
668 	SWFFilterList list;
669 
670 	list = (SWFFilterList)malloc(sizeof(struct SWFFilterList_s));
671         list->numFilter = 0;
672         list->filter = NULL;
673 	return list;
674 }
675 
SWFFilterList_add(SWFFilterList list,SWFFilter filter)676 void SWFFilterList_add(SWFFilterList list, SWFFilter filter)
677 {
678 	int count = list->numFilter;
679         list->filter = (SWFFilter*)realloc(list->filter, (count + 1) * sizeof(SWFFilter));
680         list->filter[count] = filter;
681         list->numFilter++;
682 }
683 
SWFOutput_writeFilterList(SWFOutput out,SWFFilterList list)684 void SWFOutput_writeFilterList(SWFOutput out, SWFFilterList list)
685 {
686 	int i;
687 	if(list->numFilter <= 0)
688 		return;
689 
690 	SWFOutput_writeUInt8(out, list->numFilter);
691 	for(i = 0; i < list->numFilter; i++)
692 		SWFOutput_writeSWFFilter(out, list->filter[i]);
693 }
694 
destroySWFFilterList(SWFFilterList list)695 void destroySWFFilterList(SWFFilterList list)
696 {
697 	free(list->filter);
698 	free(list);
699 }
700