+void growGradient(GRADIENT* start, int size)
+{
+ while (start->num < size)
+ insertOptimalNode(start);
+}
+
+GRADIENT* interpolateGradient(GRADIENT* g1, GRADIENT* g2, float fraction, interpolation_t* inter)
+{
+ int i;
+ GRADIENT g;
+ g.ratios = rfx_calloc(16*sizeof(U8));
+ g.rgba = rfx_calloc(16*sizeof(RGBA));
+
+ if (g1->num > g2->num)
+ {
+ copyGradient(&g, g2);
+ growGradient(&g, g1->num);
+ GRADIENT* result = interpolateNodes(g1, &g, fraction, inter);
+ rfx_free(g.rgba);
+ rfx_free(g.ratios);
+ return result;
+ }
+ else
+ if (g1->num < g2->num)
+ {
+ copyGradient(&g, g1);
+ growGradient(&g, g2->num);
+ GRADIENT* result = interpolateNodes(&g, g2, fraction, inter);
+ rfx_free(g.rgba);
+ rfx_free(g.ratios);
+ return result;
+ }
+ else
+ return interpolateNodes(g1, g2, fraction, inter);
+}
+
+FILTER* copyFilter(FILTER* original)
+{
+ if (!original)
+ return original;
+ FILTER* copy = swf_NewFilter(original->type);
+ switch (original->type)
+ {
+ case FILTERTYPE_BLUR:
+ memcpy(copy, original, sizeof(FILTER_BLUR));
+ break;
+ case FILTERTYPE_GRADIENTGLOW:
+ {
+ memcpy(copy, original, sizeof(FILTER_GRADIENTGLOW));
+ FILTER_GRADIENTGLOW* ggcopy = (FILTER_GRADIENTGLOW*)copy;
+ ggcopy->gradient = (GRADIENT*)malloc(sizeof(GRADIENT));
+ ggcopy->gradient->ratios = (U8*)malloc(16 * sizeof(U8));
+ ggcopy->gradient->rgba = (RGBA*)malloc(16 * sizeof(RGBA));
+ copyGradient(ggcopy->gradient, ((FILTER_GRADIENTGLOW*)original)->gradient);
+ }
+ break;
+ case FILTERTYPE_DROPSHADOW:
+ memcpy(copy, original, sizeof(FILTER_DROPSHADOW));
+ break;
+ case FILTERTYPE_BEVEL:
+ memcpy(copy, original, sizeof(FILTER_BEVEL));
+ break;
+ default: syntaxerror("Internal error: unsupported filterype, cannot copy");
+ }
+ return copy;
+}
+
+FILTER* interpolateBlur(FILTER* filter1, FILTER* filter2, float ratio, interpolation_t* inter)