[Top][All Lists]
[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);
~~~~~~~~~~
more_filters.diff
Description: Attachment: more_filters.diff
- [Swftools-common] [Patch] adding support for CONVOLUTION, COLORMATRIX, and GRADIENTBEVEL filters,
Jos Castellani <=