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