Merge pull request #8 from scottdraves/erik_dev

hsv_rgb_palette_blend implementation
This commit is contained in:
Scott Draves 2015-04-28 21:53:38 -04:00
commit 035ab3d4e9
5 changed files with 74 additions and 66 deletions

View File

@ -39,6 +39,7 @@ void test_cp(flam3_genome *cp) {
cp->time = 0.0; cp->time = 0.0;
cp->interpolation = flam3_interpolation_linear; cp->interpolation = flam3_interpolation_linear;
cp->palette_interpolation = flam3_palette_interpolation_hsv; cp->palette_interpolation = flam3_palette_interpolation_hsv;
cp->hsv_rgb_palette_blend = 0.0;
cp->background[0] = 0.0; cp->background[0] = 0.0;
cp->background[1] = 0.0; cp->background[1] = 0.0;
cp->background[2] = 0.0; cp->background[2] = 0.0;
@ -248,7 +249,8 @@ void spin(int frame, double blend, flam3_genome *parent, flam3_genome *templ)
/* Set genome parameters accordingly */ /* Set genome parameters accordingly */
result->time = (double)frame; result->time = (double)frame;
result->interpolation = flam3_interpolation_linear; result->interpolation = flam3_interpolation_linear;
result->palette_interpolation = flam3_palette_interpolation_hsv; result->palette_interpolation = flam3_palette_interpolation_hsv_circular;
result->hsv_rgb_palette_blend = 0.0;
/* Force linear interpolation - unsure if this is still necessary */ /* Force linear interpolation - unsure if this is still necessary */
/* I believe we put this in so that older clients could render frames */ /* I believe we put this in so that older clients could render frames */

16
flam3.c
View File

@ -785,7 +785,8 @@ void flam3_interpolate(flam3_genome cps[], int ncps,
result->time = time; result->time = time;
result->interpolation = flam3_interpolation_linear; result->interpolation = flam3_interpolation_linear;
result->interpolation_type = cpi[0].interpolation_type; result->interpolation_type = cpi[0].interpolation_type;
result->palette_interpolation = flam3_palette_interpolation_hsv; result->palette_interpolation = flam3_palette_interpolation_hsv_circular;
result->hsv_rgb_palette_blend = 0.0;
if (!smoothflag) { if (!smoothflag) {
flam3_interpolate_n(result, 2, cpi, c, stagger); flam3_interpolate_n(result, 2, cpi, c, stagger);
@ -1282,6 +1283,7 @@ void clear_cp(flam3_genome *cp, int default_flag) {
cp->pixels_per_unit = 50; cp->pixels_per_unit = 50;
cp->interpolation = flam3_interpolation_linear; cp->interpolation = flam3_interpolation_linear;
cp->palette_interpolation = flam3_palette_interpolation_hsv_circular; cp->palette_interpolation = flam3_palette_interpolation_hsv_circular;
cp->hsv_rgb_palette_blend = 0.0;
cp->genome_index = 0; cp->genome_index = 0;
memset(cp->parent_fname,0,flam3_parent_fn_len); memset(cp->parent_fname,0,flam3_parent_fn_len);
@ -1618,6 +1620,8 @@ void flam3_apply_template(flam3_genome *cp, flam3_genome *templ) {
cp->palette_mode = templ->palette_mode; cp->palette_mode = templ->palette_mode;
if (templ->palette_interpolation >= 0) if (templ->palette_interpolation >= 0)
cp->palette_interpolation = templ->palette_interpolation; cp->palette_interpolation = templ->palette_interpolation;
if (templ->hsv_rgb_palette_blend >= 0)
cp->hsv_rgb_palette_blend = templ->hsv_rgb_palette_blend;
} }
@ -1785,8 +1789,13 @@ void flam3_print(FILE *f, flam3_genome *cp, char *extra_attributes, int print_ed
fprintf(f, " palette_interpolation=\"sweep\""); fprintf(f, " palette_interpolation=\"sweep\"");
else if (flam3_palette_interpolation_rgb == cp->palette_interpolation) else if (flam3_palette_interpolation_rgb == cp->palette_interpolation)
fprintf(f, " palette_interpolation=\"rgb\""); fprintf(f, " palette_interpolation=\"rgb\"");
else if (flam3_palette_interpolation_hsv_circular == cp->palette_interpolation) else if (flam3_palette_interpolation_hsv == cp->palette_interpolation)
fprintf(f, " palette_interpolation=\"hsv\"");
else if (flam3_palette_interpolation_hsv_circular == cp->palette_interpolation) {
fprintf(f, " palette_interpolation=\"hsv_circular\""); fprintf(f, " palette_interpolation=\"hsv_circular\"");
if (cp->hsv_rgb_palette_blend > 0.0)
fprintf(f, " hsv_rgb_palette_blend=\"%g\"", cp->hsv_rgb_palette_blend);
}
if (extra_attributes) if (extra_attributes)
fprintf(f, " %s", extra_attributes); fprintf(f, " %s", extra_attributes);
@ -3087,7 +3096,8 @@ void flam3_random(flam3_genome *cp, int *ivars, int ivars_n, int sym, int spec_x
fprintf(stderr,"error getting palette from xml file, setting to all white\n"); fprintf(stderr,"error getting palette from xml file, setting to all white\n");
cp->time = 0.0; cp->time = 0.0;
cp->interpolation = flam3_interpolation_linear; cp->interpolation = flam3_interpolation_linear;
cp->palette_interpolation = flam3_palette_interpolation_hsv; cp->palette_interpolation = flam3_palette_interpolation_hsv_circular;
cp->hsv_rgb_palette_blend = 0.0;
/* Choose the number of xforms */ /* Choose the number of xforms */
if (spec_xforms>0) { if (spec_xforms>0) {

View File

@ -453,6 +453,7 @@ typedef struct {
int interpolation; int interpolation;
int interpolation_type; int interpolation_type;
int palette_interpolation; int palette_interpolation;
double hsv_rgb_palette_blend;
int num_xforms; int num_xforms;
int final_xform_index; int final_xform_index;
int final_xform_enable; int final_xform_enable;

View File

@ -372,83 +372,75 @@ double get_stagger_coef(double t, double stagger_prc, int num_xforms, int this_x
and have final xform in the same slot) */ and have final xform in the same slot) */
void flam3_interpolate_n(flam3_genome *result, int ncp, void flam3_interpolate_n(flam3_genome *result, int ncp,
flam3_genome *cpi, double *c, double stagger) { flam3_genome *cpi, double *c, double stagger) {
int i, j, k, numstd; int i, j, k, l, numstd;
// fprintf(stderr, "xxx pi=%d\n", cpi[0].palette_interpolation);
if (flam3_palette_interpolation_sweep != cpi[0].palette_interpolation) { if (flam3_palette_interpolation_sweep != cpi[0].palette_interpolation) {
/* rgb, hsv or hsv_circular modes. */
double rgb_fraction = 0.0; /* Assume that we are in plain hsv mode */
if (flam3_palette_interpolation_rgb == cpi[0].palette_interpolation)
rgb_fraction = 1.0; /* All RGB output */
else if (flam3_palette_interpolation_hsv_circular == cpi[0].palette_interpolation)
rgb_fraction = cpi[0].hsv_rgb_palette_blend;
for (i = 0; i < 256; i++) { for (i = 0; i < 256; i++) {
double t[3], s[5]; double col_rgb[3], col_hsv[3];
double new_rgb[3] = {0, 0, 0};
double new_hsv[3] = {0, 0, 0};
double new_count = 0, new_index = 0;
int alpha1 = 1; int alpha1 = 1;
s[0] = s[1] = s[2] = s[3] = s[4] = 0.0; /* Loop over each control point's color at this index */
for (k = 0; k < ncp; k++) { for (k = 0; k < ncp; k++) {
if (i == 0) {
// fprintf(stderr, "ncp=%d, k=%d\n", ncp, k); /* Convert to hsv */
// fprintf(stderr, "rgb=%g %g %g\n", cpi[k].palette[i].color[0], cpi[k].palette[i].color[1], cpi[k].palette[i].color[2]); rgb2hsv(cpi[k].palette[i].color, col_hsv);
/* Store the rgb */
for (l = 0; l < 3; l++)
col_rgb[l] = cpi[k].palette[i].color[l];
if (2 == ncp && k == 0 && cpi[0].palette_interpolation == flam3_palette_interpolation_hsv_circular) {
/* only adjust the first coordinate based on the other control point's hue */
double second_color[3];
rgb2hsv(cpi[1].palette[i].color, second_color);
/* Adjust the hue so that we go the shorter direction around the circle */
if ((second_color[0] - col_hsv[0]) > 3.0) {
col_hsv[0] += 6.0;
} else if ((second_color[0] - col_hsv[0]) < -3.0) {
col_hsv[0] -= 6.0;
}
} }
if (flam3_palette_interpolation_rgb != cpi[0].palette_interpolation)
rgb2hsv(cpi[k].palette[i].color, t); for (j = 0; j < 3; j++) {
else { new_rgb[j] += c[k] * col_rgb[j];
int l; new_hsv[j] += c[k] * col_hsv[j];
for (l = 0; l < 3; l++)
t[l] = cpi[k].palette[i].color[l];
} }
// if (i == 0) {
// fprintf(stderr, "hsv=%g %g %g\n", t[0], t[1], t[2]); /* Compute the other two components of the color (count and index) */
// } new_count += c[k] * cpi[k].palette[i].color[3];
if (2 == ncp && k == 0 &&cpi[0].palette_interpolation == flam3_palette_interpolation_hsv_circular) {
/* should also support blending between rgb and hsv,
and change the color of the cut, so we can keep
a dominant color but control what it is. */
/* only adjust the first coordinate based on the other control point's hue */
double second_color[3];
rgb2hsv(cpi[1].palette[i].color, second_color);
/* Adjust the hue so that we go the shorter direction around the circle */
if ((second_color[0] - t[0]) > 3.0) {
t[0] += 6.0;
} else if ((second_color[0] - t[0]) < -3.0) {
t[0] -= 6.0;
}
}
for (j = 0; j < 3; j++)
s[j] += c[k] * t[j];
s[3] += c[k] * cpi[k].palette[i].color[3];
if (cpi[k].palette[i].color[3] != 1.0) if (cpi[k].palette[i].color[3] != 1.0)
alpha1 = 0; alpha1 = 0;
s[4] += c[k] * cpi[k].palette[i].index; new_index += c[k] * cpi[k].palette[i].index;
} }
if (alpha1 == 1) if (alpha1 == 1)
s[3] = 1.0; new_count = 1.0;
// if (i == 0) /* Convert the new hsv coord to back rgb */
// fprintf(stderr, "s0=%g\n", s[0]); double new_hsv_rgb[3];
hsv2rgb(new_hsv, new_hsv_rgb);
if (flam3_palette_interpolation_rgb != cpi[0].palette_interpolation)
hsv2rgb(s, result->palette[i].color);
else {
int l;
for (l = 0; l < 3; l++)
result->palette[i].color[l] = s[l];
}
result->palette[i].color[3] = s[3];
result->palette[i].index = s[4];
// if (i == 0) /* Store the interpolated color in the new palette */
// fprintf(stderr, "result rgb=%g %g %g\n", for (l = 0; l < 3; l++)
// result->palette[0].color[0], result->palette[i].color[l] = rgb_fraction * new_rgb[l] + (1.0-rgb_fraction) * new_hsv_rgb[l];
// result->palette[0].color[1],
// result->palette[0].color[2]); result->palette[i].color[3] = new_count;
result->palette[i].index = new_index;
/* Clip the new color appropriately */
for (j = 0; j < 4; j++) { for (j = 0; j < 4; j++) {
if (result->palette[i].color[j] < 0.0) if (result->palette[i].color[j] < 0.0)
result->palette[i].color[j] = 0.0; result->palette[i].color[j] = 0.0;
@ -477,6 +469,7 @@ void flam3_interpolate_n(flam3_genome *result, int ncp,
result->interpolation_type = cpi[0].interpolation_type; result->interpolation_type = cpi[0].interpolation_type;
result->palette_interpolation = cpi[0].palette_interpolation; result->palette_interpolation = cpi[0].palette_interpolation;
result->hsv_rgb_palette_blend = cpi[0].hsv_rgb_palette_blend;
INTERP(brightness); INTERP(brightness);
INTERP(contrast); INTERP(contrast);
INTERP(highlight_power); INTERP(highlight_power);

View File

@ -332,6 +332,8 @@ int parse_flame_element(xmlNode *flame_node, flam3_genome *loc_current_cp) {
/* Compare attribute names */ /* Compare attribute names */
if (!xmlStrcmp(cur_att->name, (const xmlChar *)"time")) { if (!xmlStrcmp(cur_att->name, (const xmlChar *)"time")) {
cp->time = flam3_atof(att_str); cp->time = flam3_atof(att_str);
} else if (!xmlStrcmp(cur_att->name, (const xmlChar *)"hsv_rgb_palette_blend")) {
cp->hsv_rgb_palette_blend = flam3_atof(att_str);
} else if (!xmlStrcmp(cur_att->name, (const xmlChar *)"interpolation")) { } else if (!xmlStrcmp(cur_att->name, (const xmlChar *)"interpolation")) {
if (!strcmp("linear", att_str)) { if (!strcmp("linear", att_str)) {
cp->interpolation = flam3_interpolation_linear; cp->interpolation = flam3_interpolation_linear;