/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- newSWFShadow
- destroySWFShadow
- newSWFBlur
- destroySWFBlur
- newSWFFilterMatrix
- destroySWFFilterMatrix
- writeDropShadowFilter
- writeBlurFilter
- writeGlowFilter
- writeBevelFilter
- writeGradientGlowFilter
- writeConvolutionFilter
- writeColorMatrixFilter
- writeGradientBevelFilter
- SWFOutput_writeSWFFilter
- destroySWFFilter
- newColorMatrixFilter
- newConvolutionFilter
- newGradientBevelFilter
- newGradientGlowFilter
- newBevelFilter
- newGlowFilter
- newBlurFilter
- newDropShadowFilter
- newSWFFilterList
- SWFFilterList_add
- SWFOutput_writeFilterList
- destroySWFFilterList
/*
Ming, an SWF output library
Copyright (C) 2008 Klaus Rechert
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* $Id: filter.c,v 1.8 2008/09/28 16:53:59 krechert Exp $ */
#ifndef __C2MAN__
#include <stdlib.h>
#include <string.h>
#endif
#include "gradient.h"
#include "output.h"
#include "filter.h"
#include "error.h"
#include "libming.h"
struct Shadow_s
{
float angle;
float distance;
float strength;
};
/*
* create a new SWFShadow (contructor)
* This Function creates a new SWFShadow object. Only useful for creating
* SWFFilter objects.
*/
SWFShadow
newSWFShadow(float angle /* angle in radians */,
float distance /* distance in px*/,
float strength /* strength */)
{
SWFShadow shadow = (SWFShadow)malloc(sizeof(struct Shadow_s));
shadow->angle = angle;
shadow->distance = distance;
shadow->strength = strength;
return shadow;
}
void destroySWFShadow(SWFShadow s)
{
free(s);
}
struct Blur_s
{
float blurX;
float blurY;
int passes;
};
/*
* create a new SWFBlur
* This function creates a new SWFBlur object. Only useful for creating
* SWFFilter objects
*/
SWFBlur
newSWFBlur(float blurX /* horiz. blur amount */,
float blurY /* vert. blur amount */,
int passes /* number of passes. shoub be <= 3 */)
{
SWFBlur blur = (SWFBlur)malloc(sizeof(struct Blur_s));
blur->blurX = blurX;
blur->blurY = blurY;
blur->passes = passes;
return blur;
}
void destroySWFBlur(SWFBlur b)
{
free(b);
}
struct BlurFilter
{
SWFBlur blur;
};
struct DropShadowFilter
{
SWFColor color;
SWFBlur blur;
SWFShadow shadow;
int flags;
};
struct GlowFilter
{
SWFColor color;
SWFBlur blur;
float strength;
int flags;
};
struct BevelFilter
{
SWFColor shadowColor;
SWFColor highlightColor;
SWFBlur blur;
SWFShadow shadow;
int flags;
};
struct GradientGlowFilter
{
SWFGradient gradient;
SWFBlur blur;
SWFShadow shadow;
int flags;
};
struct GradientBevelFilter
{
SWFGradient gradient;
SWFBlur blur;
SWFShadow shadow;
int flags;
};
struct FilterMatrix_s
{
int cols;
int rows;
float *values;
};
/*
* create a new FilterMatrix (constructor)
* This function creates a new SFWFilterMatrix. Only useful
* for creating SWFFilter objects.
*/
SWFFilterMatrix
newSWFFilterMatrix(int cols /* number of cols */,
int rows /* number of rows */,
float *vals /* vals[cols * rows]. Will be copied */)
{
SWFFilterMatrix matrix;
if(cols <= 0 || rows <= 0)
return NULL;
matrix = (SWFFilterMatrix)malloc(sizeof(struct FilterMatrix_s));
matrix->cols = cols;
matrix->rows = rows;
matrix->values = (float *)malloc(cols * rows * sizeof(float));
memcpy(matrix->values, vals, cols * rows * sizeof(float));
return matrix;
}
void destroySWFFilterMatrix(SWFFilterMatrix m)
{
if(m == NULL)
return;
free(m->values);
free(m);
}
struct ConvolutionFilter
{
SWFFilterMatrix matrix;
float divisor;
float bias;
SWFColor color;
int flags;
};
struct ColorMatrixFilter
{
SWFFilterMatrix matrix;
};
struct SWFFilter_s
{
int id;
union {
struct DropShadowFilter dropShadow;
struct BlurFilter blur;
struct GlowFilter glow;
struct BevelFilter bevel;
struct GradientGlowFilter gradientGlow;
struct ConvolutionFilter convolution;
struct ColorMatrixFilter colorMatrix;
struct GradientBevelFilter gradientBevel;
} filter;
};
static void writeDropShadowFilter(SWFOutput out, struct DropShadowFilter *filter)
{
int flags = FILTER_MODE_COMPOSITE;
SWFOutput_writeUInt8(out, filter->color.red);
SWFOutput_writeUInt8(out, filter->color.green);
SWFOutput_writeUInt8(out, filter->color.blue);
SWFOutput_writeUInt8(out, filter->color.alpha);
SWFOutput_writeFixed(out, filter->blur->blurX);
SWFOutput_writeFixed(out, filter->blur->blurY);
SWFOutput_writeFixed(out, filter->shadow->angle);
SWFOutput_writeFixed(out, filter->shadow->distance);
SWFOutput_writeFixed8(out, filter->shadow->strength);
flags |= filter->flags;
flags |= (0x1F & filter->blur->passes);
SWFOutput_writeUInt8(out, flags);
}
static void writeBlurFilter(SWFOutput out, struct BlurFilter *filter)
{
int flags = 0;
SWFOutput_writeFixed(out, filter->blur->blurX);
SWFOutput_writeFixed(out, filter->blur->blurY);
flags = 0xff & (filter->blur->passes << 3);
SWFOutput_writeUInt8(out, flags);
}
static void writeGlowFilter(SWFOutput out, struct GlowFilter *filter)
{
int flags = FILTER_MODE_COMPOSITE;
SWFOutput_writeUInt8(out, filter->color.red);
SWFOutput_writeUInt8(out, filter->color.green);
SWFOutput_writeUInt8(out, filter->color.blue);
SWFOutput_writeUInt8(out, filter->color.alpha);
SWFOutput_writeFixed(out, filter->blur->blurX);
SWFOutput_writeFixed(out, filter->blur->blurY);
SWFOutput_writeFixed8(out, filter->strength);
flags |= filter->flags;
flags |= (0x1F & filter->blur->passes);
SWFOutput_writeUInt8(out, flags);
}
static void writeBevelFilter(SWFOutput out, struct BevelFilter *filter)
{
int flags = FILTER_MODE_COMPOSITE;
SWFOutput_writeUInt8(out, filter->shadowColor.red);
SWFOutput_writeUInt8(out, filter->shadowColor.green);
SWFOutput_writeUInt8(out, filter->shadowColor.blue);
SWFOutput_writeUInt8(out, filter->shadowColor.alpha);
SWFOutput_writeUInt8(out, filter->highlightColor.red);
SWFOutput_writeUInt8(out, filter->highlightColor.green);
SWFOutput_writeUInt8(out, filter->highlightColor.blue);
SWFOutput_writeUInt8(out, filter->highlightColor.alpha);
SWFOutput_writeFixed(out, filter->blur->blurX);
SWFOutput_writeFixed(out, filter->blur->blurY);
SWFOutput_writeFixed(out, filter->shadow->angle);
SWFOutput_writeFixed(out, filter->shadow->distance);
SWFOutput_writeFixed8(out, filter->shadow->strength);
flags |= filter->flags;
flags |= (0xF & filter->blur->passes);
SWFOutput_writeUInt8(out, flags);
}
static void writeGradientGlowFilter(SWFOutput out, struct GradientGlowFilter *filter)
{
int flags = FILTER_MODE_COMPOSITE;
SWFOutput_writeGradientAsFilter(out, filter->gradient);
SWFOutput_writeFixed(out, filter->blur->blurX);
SWFOutput_writeFixed(out, filter->blur->blurY);
SWFOutput_writeFixed(out, filter->shadow->angle);
SWFOutput_writeFixed(out, filter->shadow->distance);
SWFOutput_writeFixed8(out, filter->shadow->strength);
flags |= filter->flags;
flags |= (0xF & filter->blur->passes);
SWFOutput_writeUInt8(out, flags);
}
static void writeConvolutionFilter(SWFOutput out, struct ConvolutionFilter *filter)
{
int i;
SWFOutput_writeUInt8(out, filter->matrix->cols);
SWFOutput_writeUInt8(out, filter->matrix->rows);
SWFOutput_writeFloat(out, filter->divisor);
SWFOutput_writeFloat(out, filter->bias);
for(i = 0; i < filter->matrix->cols * filter->matrix->rows; i++)
SWFOutput_writeFloat(out, filter->matrix->values[i]);
SWFOutput_writeUInt8(out, filter->color.red);
SWFOutput_writeUInt8(out, filter->color.green);
SWFOutput_writeUInt8(out, filter->color.blue);
SWFOutput_writeUInt8(out, filter->color.alpha);
SWFOutput_writeUInt8(out, filter->flags);
}
static void writeColorMatrixFilter(SWFOutput out, struct ColorMatrixFilter *filter)
{
int i;
for(i = 0; i < filter->matrix->rows * filter->matrix->cols; i++)
SWFOutput_writeFloat(out, filter->matrix->values[i]);
}
static void writeGradientBevelFilter(SWFOutput out, struct GradientBevelFilter *filter)
{
int flags = FILTER_MODE_COMPOSITE;
SWFOutput_writeGradientAsFilter(out, filter->gradient);
SWFOutput_writeFixed(out, filter->blur->blurX);
SWFOutput_writeFixed(out, filter->blur->blurY);
SWFOutput_writeFixed(out, filter->shadow->angle);
SWFOutput_writeFixed(out, filter->shadow->distance);
SWFOutput_writeFixed8(out, filter->shadow->strength);
flags |= filter->flags;
flags |= (0xF & filter->blur->passes);
SWFOutput_writeUInt8(out, flags);
}
void
SWFOutput_writeSWFFilter(SWFOutput out, SWFFilter filter)
{
if(out == NULL || filter == NULL)
return;
SWFOutput_writeUInt8(out, filter->id);
switch(filter->id)
{
case SWFFILTER_TYPE_DROPSHADOW:
writeDropShadowFilter(out, &filter->filter.dropShadow);
break;
case SWFFILTER_TYPE_BLUR:
writeBlurFilter(out, &filter->filter.blur);
break;
case SWFFILTER_TYPE_GLOW:
writeGlowFilter(out, &filter->filter.glow);
break;
case SWFFILTER_TYPE_BEVEL:
writeBevelFilter(out, &filter->filter.bevel);
break;
case SWFFILTER_TYPE_GRADIENTGLOW:
writeGradientGlowFilter(out, &filter->filter.gradientGlow);
break;
case SWFFILTER_TYPE_CONVOLUTION:
writeConvolutionFilter(out, &filter->filter.convolution);
break;
case SWFFILTER_TYPE_COLORMATRIX:
writeColorMatrixFilter(out, &filter->filter.colorMatrix);
break;
case SWFFILTER_TYPE_GRADIENTBEVEL:
writeGradientBevelFilter(out, &filter->filter.gradientBevel);
break;
default:
SWF_error("destroySWFFilter: invalid filter\n");
}
}
void
destroySWFFilter(SWFFilter filter)
{
if(filter == NULL)
return;
switch(filter->id)
{
case SWFFILTER_TYPE_DROPSHADOW:
// destroyDropShadowFilter(&filter->filter.dropShadow);
break;
case SWFFILTER_TYPE_BLUR:
// destroyBlurFilter(&filter->filter.blur);
break;
case SWFFILTER_TYPE_GLOW:
// destroyGlowFilter(&filter->filter.glow);
break;
case SWFFILTER_TYPE_BEVEL:
//destroyBevelFilter(&filter->filter.bevel);
break;
case SWFFILTER_TYPE_GRADIENTGLOW:
// destroyGradientGlowFilter(&filter->filter.gradientGlow);
break;
case SWFFILTER_TYPE_CONVOLUTION:
// destroyConvolutionFilter(&filter->filter.convolution);
break;
case SWFFILTER_TYPE_COLORMATRIX:
// destroyColorMatrixFilter(&filter->filter.colorMatrix);
break;
case SWFFILTER_TYPE_GRADIENTBEVEL:
// destroyGradientBevelFilter(&filter->filter.gradientBevel);
break;
default:
SWF_error("destroySWFFilter: invalid filter\n");
}
free(filter);
}
/*
* creates a new ColormatrixFilter
* Matrix has to be 5 x 4
* [r0 ... r4]
* [g0 ... g4]
* [b0 ... b4]
* [a0 ... a4]
*/
SWFFilter
newColorMatrixFilter(SWFFilterMatrix matrix /* matrix */)
{
SWFFilter filter;
if(matrix == NULL)
return NULL;
if(matrix->rows != 4 || matrix->cols != 5)
{
SWF_warn("newColorMatrixFilter: color matrix has to be 5x4\n");
return NULL;
}
filter = (SWFFilter)malloc(sizeof(struct SWFFilter_s));
filter->id = SWFFILTER_TYPE_COLORMATRIX;
filter->filter.colorMatrix.matrix = matrix;
return filter;
}
/*
* creates a new ConvolutionFilter
*/
SWFFilter
newConvolutionFilter(SWFFilterMatrix matrix /* matrix */,
float divisor /* divisor applied to matrix */,
float bias /* matrix bias */,
SWFColor color /* default color */,
int flags /* FILTER_FLAG_CLAMP , FILTER_FLAG_PRESERVE_ALPHA */)
{
SWFFilter filter;
struct ConvolutionFilter *convolution;
if(matrix == NULL)
return NULL;
filter = (SWFFilter)malloc(sizeof(struct SWFFilter_s));
filter->id = SWFFILTER_TYPE_CONVOLUTION;
convolution = &filter->filter.convolution;
convolution->matrix = matrix;
convolution->divisor = divisor;
convolution->bias = bias;
convolution->color = color;
convolution->flags = flags;
return filter;
}
/*
* create a GradientBevelFilter
* This functions creates a gradient bevel filter. Extends BevelFilter by
* using a gradient instead of a simple color
*/
SWFFilter
newGradientBevelFilter(SWFGradient gradient /* gradient */,
SWFBlur blur /* blur */,
SWFShadow shadow /* shadow */,
int flags /* FILTER_MODE_INNER, FILTER_MODE_KO, FILTER_MODE_ONTOP */)
{
SWFFilter filter;
struct GradientBevelFilter *gBevel;
if(gradient == NULL || blur == NULL)
return NULL;
filter = (SWFFilter)malloc(sizeof(struct SWFFilter_s));
filter->id = SWFFILTER_TYPE_GRADIENTBEVEL;
gBevel = &filter->filter.gradientBevel;
gBevel->gradient = gradient;
gBevel->blur = blur;
gBevel->shadow = shadow;
gBevel->flags = flags;
return filter;
}
/*
* creates a GardientGlowFilter
* This functions creates a gradient glow filter. Extends GlowFilter by
* using a gradient instead of a simple color
*/
SWFFilter
newGradientGlowFilter(SWFGradient gradient /* gradient */,
SWFBlur blur /* blur */,
SWFShadow shadow /* shadow */,
int flags /* FILTER_MODE_INNER, FILTER_MODE_KO, FILTER_MODE_ONTOP */)
{
SWFFilter filter;
struct GradientGlowFilter *gGlow;
if(gradient == NULL || blur == NULL)
return NULL;
filter = (SWFFilter)malloc(sizeof(struct SWFFilter_s));
filter->id = SWFFILTER_TYPE_GRADIENTGLOW;
gGlow = &filter->filter.gradientGlow;
gGlow->gradient = gradient;
gGlow->blur = blur;
gGlow->shadow = shadow;
gGlow->flags = flags;
return filter;
}
/*
* creates a BevelFilter
* This functions creates a bevel filter. Creates a smooth bevel
*/
SWFFilter
newBevelFilter(SWFColor shadowColor /* shadow color */,
SWFColor highlightColor /* highlight color */,
SWFBlur blur /* blur */,
SWFShadow shadow /* shadow */,
int flags /* FILTER_MODE_INNER, FILTER_MODE_KO, FILTER_MODE_ONTOP */)
{
SWFFilter filter;
struct BevelFilter *bevel;
if(blur == NULL || shadow == NULL)
return NULL;
filter = (SWFFilter)malloc(sizeof(struct SWFFilter_s));
filter->id = SWFFILTER_TYPE_BEVEL;
bevel = &filter->filter.bevel;
bevel->shadowColor = shadowColor;
bevel->highlightColor = highlightColor;
bevel->blur = blur;
bevel->shadow = shadow;
bevel->flags = flags;
return filter;
}
/*
* creates a GlowFilter
* This functions creates a glow filter.
*/
SWFFilter
newGlowFilter(SWFColor color /* color of shadow */,
SWFBlur blur /* blur */,
float strength /* strength */,
int flags /* FILTER_MODE_INNER, FILTER_MODE_KO */)
{
SWFFilter filter;
struct GlowFilter *glow;
if(blur == NULL)
return NULL;
filter = (SWFFilter)malloc(sizeof(struct SWFFilter_s));
filter->id = SWFFILTER_TYPE_GLOW;
glow = &filter->filter.glow;
glow->color = color;
glow->blur = blur;
glow->strength = strength;
glow->flags = flags;
return filter;
}
/*
* creates a BlurFilter
* This functions creates a blur filter.
*/
SWFFilter
newBlurFilter(SWFBlur blur /* blur */)
{
SWFFilter filter;
struct BlurFilter *b;
if(blur == NULL)
return NULL;
filter = (SWFFilter)malloc(sizeof(struct SWFFilter_s));
filter->id = SWFFILTER_TYPE_BLUR;
b = &filter->filter.blur;
b->blur = blur;
return filter;
}
/*
* creates a DropShadowFilter
* This functions creates a drop shadow filter filter.
*/
SWFFilter
newDropShadowFilter(SWFColor color /* color of shadow */,
SWFBlur blur /* blur */,
SWFShadow shadow /* shadow */,
int flags /* FILTER_MODE_INNER, FILTER_MODE_KO */)
{
struct DropShadowFilter *dropShadow;
SWFFilter filter;
if(blur == NULL || shadow == NULL)
return NULL;
filter = (SWFFilter)malloc(sizeof(struct SWFFilter_s));
filter->id = SWFFILTER_TYPE_DROPSHADOW;
dropShadow = &filter->filter.dropShadow;
dropShadow->color = color;
dropShadow->blur = blur;
dropShadow->shadow = shadow;
dropShadow->flags = flags;
return filter;
}
SWFFilterList newSWFFilterList()
{
SWFFilterList list;
list = (SWFFilterList)malloc(sizeof(struct SWFFilterList_s));
list->numFilter = 0;
list->filter = NULL;
return list;
}
void SWFFilterList_add(SWFFilterList list, SWFFilter filter)
{
int count = list->numFilter;
list->filter = (SWFFilter*)realloc(list->filter, (count + 1) * sizeof(SWFFilter));
list->filter[count] = filter;
list->numFilter++;
}
void SWFOutput_writeFilterList(SWFOutput out, SWFFilterList list)
{
int i;
if(list->numFilter <= 0)
return;
SWFOutput_writeUInt8(out, list->numFilter);
for(i = 0; i < list->numFilter; i++)
SWFOutput_writeSWFFilter(out, list->filter[i]);
}
void destroySWFFilterList(SWFFilterList list)
{
free(list->filter);
free(list);
}