summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--flam3.c4
-rw-r--r--flam3.h6
-rw-r--r--main.c55
-rw-r--r--palettes.c189
4 files changed, 142 insertions, 112 deletions
diff --git a/flam3.c b/flam3.c
index b0caaf7..0a6f59b 100644
--- a/flam3.c
+++ b/flam3.c
@@ -1736,11 +1736,11 @@ void flam3_mutate(flam3_genome *cp, int mutate_mode, int *ivars, int ivars_n, in
if (s < 0.4) { /* randomize xform color coords */
- flam3_improve_colors(cp, 100, 0, 10, pc, rc);
+ flam3_improve_colors(cp, 100, 0, 10, 1.0, pc, rc);
} else if (s < 0.8) { /* randomize xform color coords and palette */
- flam3_improve_colors(cp, 25, 1, 10, pc, rc);
+ flam3_improve_colors(cp, 25, 1, 10, 1.0, pc, rc);
} else { /* randomize palette only */
const palette * const p = palette_random (pc, rc);
diff --git a/flam3.h b/flam3.h
index b011d81..e5127fc 100644
--- a/flam3.h
+++ b/flam3.h
@@ -461,7 +461,11 @@ flam3_genome *flam3_parse_xml2(const int, int default_flag, int *ncps, randctx *
void flam3_add_symmetry(flam3_genome *cp, int sym, randctx * const rc);
-void flam3_improve_colors(flam3_genome *g, int ntries, int change_palette, int color_resolution, const palette_collection * const pc, randctx * const rc);
+void flam3_improve_colors(flam3_genome *g, unsigned int ntries,
+ bool change_palette,
+ unsigned int color_resolution, double timelimit,
+ const palette_collection * const pc,
+ randctx * const rc);
int flam3_estimate_bounding_box(flam3_genome *g, double eps, int nsamples,
double *bmin, double *bmax, randctx *rc);
diff --git a/main.c b/main.c
index 909db71..ec6205d 100644
--- a/main.c
+++ b/main.c
@@ -422,11 +422,38 @@ static void do_cross (const cross_arguments * const arguments) {
print_genome (&genome_out);
}
-#if 0
-static void do_improvecolors () {
- flam3_improve_colors(&cp_orig, 100, 0, 10, &rc);
+typedef struct {
+ unsigned int tries, resolution;
+ bool change_palette;
+ double time;
+} improvecolors_arguments;
+
+static error_t parse_improvecolors_opt (int key, char *arg,
+ struct argp_state * const state) {
+ improvecolors_arguments * const arguments = state->input;
+
+ return 0;
+}
+
+static void do_improvecolors (const improvecolors_arguments * const arguments) {
+ randctx rc;
+
+ rand_seed(&rc);
+
+ int ncps;
+ flam3_genome * const cps = flam3_parse_xml2 (STDIN_FILENO,
+ flam3_defaults_on, &ncps, &rc);
+ if (cps == NULL) {
+ fprintf(stderr,"error reading genomes from file\n");
+ exit(1);
+ }
+ assert (ncps == 1);
+
+ flam3_improve_colors (&cps[0], arguments->tries, arguments->change_palette,
+ arguments->resolution, arguments->time, &builtin_palettes, &rc);
+
+ print_genome (&cps[0]);
}
-#endif
typedef struct {
float time;
@@ -495,6 +522,7 @@ static void show_help (const char * const argv0) {
}
fprintf (stderr,
"Usage: %s cross [OPTION...]\n"
+ " Or: %s improvecolors [OPTION...]\n"
" Or: %s interpolate [OPTION...]\n"
" Or: %s mutate [OPTION...]\n"
" Or: %s random [OPTION...]\n"
@@ -527,6 +555,25 @@ int main (int argc, char **argv) {
argp_parse (&argp, argc, argv, 0, NULL, &arguments);
do_cross (&arguments);
+ } else if (streq (command, "improvecolors")) {
+ const struct argp_option options[] = {
+ { 0 },
+ };
+ const char doc[] = PACKAGE "-improvecolors -- improve flame colors";
+ const struct argp argp = {
+ .options = options, .parser = parse_improvecolors_opt,
+ .args_doc = NULL, .doc = doc, .children = NULL
+ };
+
+ improvecolors_arguments arguments = {
+ .tries = 100,
+ .resolution = 10,
+ .change_palette = true,
+ .time = 1.0,
+ };
+
+ argp_parse (&argp, argc, argv, 0, NULL, &arguments);
+ do_improvecolors (&arguments);
} else if (streq (command, "interpolate")) {
const struct argp_option options[] = {
{"time", 't', "float", OPTION_ARG_OPTIONAL, "Time step (0.5)" },
diff --git a/palettes.c b/palettes.c
index 6da1fc5..eb13cb3 100644
--- a/palettes.c
+++ b/palettes.c
@@ -226,88 +226,66 @@ static int random_xform(flam3_genome *g, int excluded, randctx * const rc) {
return -1;
}
-static double try_colors(flam3_genome *g, int color_resolution) {
- int *hist;
- int i, hits, res = color_resolution;
- int res3 = res * res * res;
- flam3_frame f;
- unsigned char *image, *p;
- flam3_genome saved;
- double scalar;
- int pixtotal;
-
- memset(&saved, 0, sizeof(flam3_genome));
-
- flam3_copy(&saved, g);
-
- /* Scale the image so that the total number of pixels is ~10000 */
- pixtotal = g->width * g->height;
- scalar = sqrt( 10000.0 / (double)pixtotal);
- g->width *= scalar;
- g->height *= scalar;
- g->pixels_per_unit *= scalar;
-
-// g->width = 100; // XXX keep aspect ratio
-// g->height = 100;
-// g->pixels_per_unit = 50;
-
- f.bytes_per_channel=1;
- f.genomes = g;
- f.ngenomes = 1;
- f.earlyclip = 1;
- f.pixel_aspect_ratio = 1.0;
- f.progress = 0;
- f.nthreads = 1;
- f.sub_batch_size = 10000;
-
- image = (unsigned char *) calloc(g->width * g->height, 3);
+static double try_colors(flam3_genome *g, unsigned int color_resolution,
+ double timelimit) {
+ assert (g != NULL);
+ assert (color_resolution > 0);
+
+ int *hist;
+ unsigned int res = color_resolution, res3 = res * res * res;
+ unsigned char *image, *p;
+ flam3_genome saved;
+ int pixtotal;
+
+ memset(&saved, 0, sizeof(flam3_genome));
+
+ flam3_copy(&saved, g);
+
+ /* Scale the image so that the total number of pixels is ~10000 */
+ pixtotal = g->width * g->height;
+ const double scalar = sqrt( 10000.0 / (double)pixtotal);
+ g->width *= scalar;
+ g->height *= scalar;
+ g->pixels_per_unit *= scalar;
+
+ const unsigned int bytes_per_channel=1;
+ const unsigned int channels = 4;
+
+ image = (unsigned char *) calloc(g->width * g->height, bytes_per_channel * channels);
bucket bucket;
bucket_init (&bucket, (uint2) { g->width, g->height });
- render_bucket (g, &bucket, 0.2);
- render_image (g, &bucket, image, f.bytes_per_channel);
-
- hist = calloc(sizeof(int), res3);
- p = image;
- for (i = 0; i < g->height * g->width; i++) {
- hist[(p[0] * res / 256) +
- (p[1] * res / 256) * res +
- (p[2] * res / 256) * res * res]++;
- p += 3;
- }
-
- if (0) {
- int j, k;
- for (i = 0; i < res; i++) {
- fprintf(stderr, "\ni=%d: \n", i);
- for (j = 0; j < res; j++) {
- for (k = 0; k < res; k++) {
- fprintf(stderr, " %5d", hist[i * res * res + j * res + k]);
- }
- fprintf(stderr, "\n");
- }
- }
- }
-
- hits = 0;
- for (i = 0; i < res3; i++) {
- if (hist[i]) hits++;
- }
-
- free(hist);
- free(image);
-
- g->width = saved.width;
- g->height = saved.height;
- g->pixels_per_unit = saved.pixels_per_unit;
-
- /* Free xform storage */
- clear_cp(&saved,flam3_defaults_on);
-
- return (double) (hits / res3);
+ render_bucket (g, &bucket, timelimit);
+ render_image (g, &bucket, image, bytes_per_channel);
+
+ hist = calloc(sizeof(int), res3);
+ p = image;
+ for (unsigned int i = 0; i < g->height * g->width; i++) {
+ hist[(p[0] * res / 256) +
+ (p[1] * res / 256) * res +
+ (p[2] * res / 256) * res * res]++;
+ p += channels;
+ }
+
+ unsigned int hits = 0;
+ for (unsigned int i = 0; i < res3; i++) {
+ if (hist[i]) hits++;
+ }
+
+ free(hist);
+ free(image);
+
+ g->width = saved.width;
+ g->height = saved.height;
+ g->pixels_per_unit = saved.pixels_per_unit;
+
+ /* Free xform storage */
+ clear_cp(&saved,flam3_defaults_on);
+
+ return (double) hits / (double) res3;
}
-static void change_colors(flam3_genome *g, int change_palette,
+static void change_colors(flam3_genome *g, bool change_palette,
const palette_collection * const pc, randctx * const rc) {
int i;
int x0, x1;
@@ -326,34 +304,35 @@ static void change_colors(flam3_genome *g, int change_palette,
if (x1 >= 0 && rand_bool(rc)) g->xform[x1].color = 1.0;
}
-void flam3_improve_colors(flam3_genome *g, int ntries, int change_palette, int color_resolution, const palette_collection * const pc, randctx * const rc) {
- int i;
- double best, b;
- flam3_genome best_genome;
-
- memset(&best_genome, 0, sizeof(flam3_genome));
-
- best = try_colors(g, color_resolution);
- if (best<0) {
- fprintf(stderr,"error in try_colors, skipping flam3_improve_colors\n");
- return;
- }
-
- flam3_copy(&best_genome,g);
- for (i = 0; i < ntries; i++) {
- change_colors(g, change_palette, pc, rc);
- b = try_colors(g, color_resolution);
- if (b < 0) {
- fprintf(stderr,"error in try_colors, aborting tries\n");
- break;
- }
- if (b > best) {
- best = b;
- flam3_copy(&best_genome,g);
- }
- }
+void flam3_improve_colors(flam3_genome *g, unsigned int ntries,
+ bool change_palette,
+ unsigned int color_resolution, double timelimit,
+ const palette_collection * const pc,
+ randctx * const rc) {
+ const double trytime = timelimit/(double) ntries;
+ flam3_genome best_genome;
+
+ memset(&best_genome, 0, sizeof(flam3_genome));
+
+ double best = try_colors(g, color_resolution, trytime);
+ assert (best >= 0.0);
+
+ flam3_copy(&best_genome,g);
+ for (unsigned int i = 0; i < ntries; i++) {
+ change_colors(g, change_palette, pc, rc);
+ const double b = try_colors(g, color_resolution, trytime);
+ assert (b >= 0.0);
+ if (b < 0) {
+ fprintf(stderr,"error in try_colors, aborting tries\n");
+ break;
+ }
+ if (b > best) {
+ best = b;
+ flam3_copy(&best_genome,g);
+ }
+ }
- flam3_copy(g,&best_genome);
- clear_cp(&best_genome,flam3_defaults_on);
+ flam3_copy(g,&best_genome);
+ clear_cp(&best_genome,flam3_defaults_on);
}