swftools-common
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Swftools-common] [Patch] adding support for CONVOLUTION, COLORMATRIX, a


From: Jos Castellani
Subject: [Swftools-common] [Patch] adding support for CONVOLUTION, COLORMATRIX, and GRADIENTBEVEL filters
Date: Thu, 15 Nov 2012 14:11:33 +0100

This patch will add support for the filters CONVOULTION, COLORMATRIX, and 
GRADIENTBEVEL, as described in the SWFv10 specification, pages 42 through 44, 
and 49/50.
http://adobe.com/content/dam/Adobe/en/devnet/swf/pdf/swf_file_format_spec_v10.pdf

It was neccessary to add functions for reading and writing float values in 
lib/rfxswf.c

Please review.
Thanks.



diff -Nrdu3 a/lib/modules/swffilter.c b/lib/modules/swffilter.c
--- a/lib/modules/swffilter.c
+++ b/lib/modules/swffilter.c
@@ -62,6 +62,43 @@
 swf_SetFixed8(tag, f->strength);
 U8 flags = f->innershadow << 7 | f->knockout << 6 | f->composite << 5 | 
f->ontop << 4 | f->passes;
 swf_SetU8(tag, flags);
+ } else if (filter->type == FILTERTYPE_GRADIENTBEVEL) {
+ FILTER_GRADIENTBEVEL *f = (FILTER_GRADIENTBEVEL *)filter;
+ swf_SetU8(tag, f->gradient->num);
+
+ int s;
+ for (s = 0; s < f->gradient->num; s++)
+ swf_SetRGBA(tag, &f->gradient->rgba[s]);
+ for (s = 0; s < f->gradient->num; s++)
+ swf_SetU8(tag, f->gradient->ratios[s]);
+
+ swf_SetFixed(tag, f->blurx);
+ swf_SetFixed(tag, f->blury);
+ swf_SetFixed(tag, f->angle);
+ swf_SetFixed(tag, f->distance);
+ swf_SetFixed8(tag, f->strength);
+ U8 flags = f->innershadow << 7 | f->knockout << 6 | f->composite << 5 | 
f->ontop << 4 | f->passes;
+ swf_SetU8(tag, flags);
+ } else if (filter->type == FILTERTYPE_CONVOLUTION) {
+ FILTER_CONVOLUTION *f = (FILTER_CONVOLUTION *)filter;
+ swf_SetU8(tag, f->matrixx);
+ swf_SetU8(tag, f->matrixy);
+ swf_SetFloat(tag, f->divisor);
+ swf_SetFloat(tag, f->bias);
+
+ int s;
+ for (s = 0; s < f->matrixx * f->matrixy; s++)
+ swf_SetFloat(tag, f->matrix[s]);
+
+ swf_SetRGBA(tag, &f->defaultcolor);
+ U8 flags = f->clampmode << 1 | f->preservealpha;
+ swf_SetU8(tag, flags);
+ } else if (filter->type == FILTERTYPE_COLORMATRIX) {
+ FILTER_COLORMATRIX *f = (FILTER_COLORMATRIX *)filter;
+
+ int s;
+ for (s = 0; s < 20; s++)
+ swf_SetFloat(tag, f->matrix[s]);
 } else {
 fprintf(stderr, "Writing of filter type %02x not supported yet\n", 
filter->type);
 }
@@ -134,7 +171,7 @@
 f->composite = (flags >> 5) & 1;
 f->ontop = (flags >> 4) & 1;
 return (FILTER *)f;
- } else if(type == FILTERTYPE_BEVEL) {
+ } else if (type == FILTERTYPE_BEVEL) {
 FILTER_BEVEL *f = (FILTER_BEVEL *)rfx_calloc(sizeof (FILTER_BEVEL));
 f->type = type;
 swf_GetRGBA(tag, &f->shadow);
@@ -151,6 +188,58 @@
 f->composite = (flags >> 5) & 1;
 f->ontop = (flags >> 4) & 1;
 return (FILTER *)f;
+ } else if (type == FILTERTYPE_GRADIENTBEVEL) {
+ FILTER_GRADIENTBEVEL *f = (FILTER_GRADIENTBEVEL *)rfx_calloc(sizeof 
(FILTER_GRADIENTBEVEL));
+ f->type = type;
+ f->gradient = (GRADIENT *)rfx_calloc(sizeof (GRADIENT));
+ f->gradient->num = swf_GetU8(tag);
+ f->gradient->rgba = (RGBA *)rfx_calloc(sizeof (RGBA) * f->gradient->num);
+ f->gradient->ratios = (U8 *)rfx_calloc(sizeof (U8) * f->gradient->num);
+
+ int s;
+ for (s = 0; s < f->gradient->num; s++)
+ swf_GetRGBA(tag, &f->gradient->rgba[s]);
+ for (s = 0; s < f->gradient->num; s++)
+ f->gradient->ratios[s] = swf_GetU8(tag);
+
+ f->blurx = swf_GetFixed(tag);
+ f->blury = swf_GetFixed(tag);
+ f->angle = swf_GetFixed(tag);
+ f->distance = swf_GetFixed(tag);
+ f->strength = swf_GetFixed8(tag);
+ U8 flags = swf_GetU8(tag);
+ f->passes = flags & 0x0F;
+ f->innershadow = (flags >> 7) & 1;
+ f->knockout = (flags >> 6) & 1;
+ f->composite = (flags >> 5) & 1;
+ f->ontop = (flags >> 4) & 1;
+ return (FILTER *)f;
+ } else if (type == FILTERTYPE_CONVOLUTION) {
+ FILTER_CONVOLUTION *f = (FILTER_CONVOLUTION *)rfx_calloc(sizeof 
(FILTER_CONVOLUTION));
+ f->type = type;
+ f->matrixx = swf_GetU8(tag);
+ f->matrixy = swf_GetU8(tag);
+ f->divisor = swf_GetFloat(tag);
+ f->bias = swf_GetFloat(tag);
+ f->matrix = (float *)rfx_calloc(f->matrixx * f->matrixy * sizeof (float));
+
+ int s;
+ for (s = 0; s < f->matrixx * f->matrixy; s++)
+ f->matrix[s] = swf_GetFloat(tag);
+
+ swf_GetRGBA(tag, &f->defaultcolor);
+ U8 flags = swf_GetU8(tag);
+ f->clampmode = (flags >> 1) & 1;
+ f->preservealpha = flags & 1;
+ return (FILTER *)f;
+ } else if (type == FILTERTYPE_COLORMATRIX) {
+ FILTER_COLORMATRIX *f = (FILTER_COLORMATRIX *)rfx_calloc(sizeof 
(FILTER_COLORMATRIX));
+ f->type = type;
+
+ int s;
+ for (s = 0; s < 20; s++)
+ f->matrix[s] = swf_GetFloat(tag);
+ return (FILTER *)f;
 } else {
 fprintf(stderr, "Reading of filter type %02x not supported yet\n", type);
 }
@@ -177,6 +266,15 @@
 } else if (type == FILTERTYPE_BEVEL) {
 f = (FILTER *)rfx_calloc(sizeof (FILTER_BEVEL));
 memset(f, 0, sizeof (FILTER_BEVEL));
+ } else if (type == FILTERTYPE_GRADIENTBEVEL) {
+ f = (FILTER *)rfx_calloc(sizeof (FILTER_GRADIENTBEVEL));
+ memset(f, 0, sizeof (FILTER_GRADIENTBEVEL));
+ } else if (type == FILTERTYPE_CONVOLUTION) {
+ f = (FILTER *)rfx_calloc(sizeof (FILTER_CONVOLUTION));
+ memset(f, 0, sizeof (FILTER_CONVOLUTION));
+ } else if (type == FILTERTYPE_COLORMATRIX) {
+ f = (FILTER *)rfx_calloc(sizeof (FILTER_COLORMATRIX));
+ memset(f, 0, sizeof (FILTER_COLORMATRIX));
 } else {
 fprintf(stderr, "Creation of filter type %02x not supported yet\n", type);
 }
@@ -196,5 +294,14 @@
 free(((FILTER_GRADIENTGLOW *)f)->gradient->ratios);
 free(((FILTER_GRADIENTGLOW *)f)->gradient);
 }
+ if (f->type == FILTERTYPE_GRADIENTBEVEL && ((FILTER_GRADIENTBEVEL 
*)f)->gradient) {
+ if (((FILTER_GRADIENTBEVEL *)f)->gradient->rgba)
+ free(((FILTER_GRADIENTBEVEL *)f)->gradient->rgba);
+ if (((FILTER_GRADIENTBEVEL *)f)->gradient->ratios)
+ free(((FILTER_GRADIENTBEVEL *)f)->gradient->ratios);
+ free(((FILTER_GRADIENTBEVEL *)f)->gradient);
+ }
+ if (f->type == FILTERTYPE_CONVOLUTION && ((FILTER_CONVOLUTION *)f)->matrix)
+ free(((FILTER_CONVOLUTION *)f)->matrix);
 free(f);
 }
diff -Nrdu3 a/lib/rfxswf.c b/lib/rfxswf.c
--- a/lib/rfxswf.c
+++ b/lib/rfxswf.c
@@ -494,6 +494,26 @@
     return u;
 }
 
+float swf_GetFloat(TAG *tag)
+{
+    union {
+        U32 uint_bits;
+        float float_bits;
+    } f;
+    f.uint_bits = swf_GetU32(tag);
+    return f.float_bits;
+}
+
+void swf_SetFloat(TAG *tag, float v)
+{
+    union {
+        U32 uint_bits;
+        float float_bits;
+    } f;
+    f.float_bits = v;
+    swf_SetU32(tag, f.uint_bits);
+}
+
 double swf_GetD64(TAG*tag)
 {
     /* FIXME: this is not big-endian compatible */
diff -Nrdu3 a/lib/rfxswf.h b/lib/rfxswf.h
--- a/lib/rfxswf.h
+++ b/lib/rfxswf.h
@@ -248,6 +248,9 @@
 float floatToF16(float f);
 float F16toFloat(U16 x);
 
+float swf_GetFloat(TAG *tag);
+void swf_SetFloat(TAG *tag, float v);
+
 /* abc datatypes */
 U32 swf_GetU30(TAG*tag);
 int swf_SetU30(TAG*tag, U32 u);
@@ -1196,6 +1199,38 @@
     char knockout;
     char composite;
 } FILTER_GLOW;
+
+typedef struct _FILTER_GRADIENTBEVEL {
+    U8 type;
+    GRADIENT*gradient;
+    double blurx;
+    double blury;
+    double angle;
+    double distance;
+    float strength;
+    char innershadow;
+    char knockout;
+    char composite;
+    char ontop;
+    int passes;
+} FILTER_GRADIENTBEVEL;
+
+typedef struct _FILTER_CONVOLUTION {
+    U8 type;
+    U8 matrixx;
+    U8 matrixy;
+    float divisor;
+    float bias;
+    float *matrix;
+    RGBA defaultcolor;
+    char clampmode;
+    char preservealpha;
+} FILTER_CONVOLUTION;
+
+typedef struct _FILTER_COLORMATRIX {
+    U8 type;
+    float matrix[20];
+} FILTER_COLORMATRIX;
 
 void swf_SetFilter(TAG*tag, FILTER*f);
 FILTER*swf_GetFilter(TAG*tag);













~~~~~~~~~~

Attachment: more_filters.diff
Description: Attachment: more_filters.diff


reply via email to

[Prev in Thread] Current Thread [Next in Thread]