summaryrefslogtreecommitdiffstats
path: root/main.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2015-10-04 15:35:30 -0400
committerTavian Barnes <tavianator@tavianator.com>2015-10-04 15:35:30 -0400
commitd95e93bf70f3351e6fd489284794ef7909fd94ce (patch)
tree0093ab92fe45d92c73e1bce97a92efe69da2866a /main.c
parent51baf3067c368e1c638f708e0d166cc2227149b0 (diff)
downloadkd-forest-d95e93bf70f3351e6fd489284794ef7909fd94ce.tar.xz
Make striping optional.
Diffstat (limited to 'main.c')
-rw-r--r--main.c123
1 files changed, 68 insertions, 55 deletions
diff --git a/main.c b/main.c
index 055c854..109f9f6 100644
--- a/main.c
+++ b/main.c
@@ -40,6 +40,10 @@ typedef struct {
uint32_t *colors;
pixel_t *pixels;
png_byte **bitmap;
+ unsigned int iteration;
+ unsigned int update_interval;
+ unsigned int frame;
+ size_t max_boundary;
} state_t;
static void init_state(state_t *state, const options_t *options);
@@ -109,6 +113,10 @@ init_state(state_t *state, const options_t *options)
state->colors = generate_colors(options);
state->pixels = create_pixels(options);
state->bitmap = create_bitmap(options);
+ state->iteration = 0;
+ state->update_interval = 1U << (state->options->bit_depth + 1)/2;
+ state->frame = 0;
+ state->max_boundary = 0;
}
static void generate_bitmap(state_t *state);
@@ -342,91 +350,96 @@ print_progress(const char *format, ...)
}
static void
-generate_bitmap(state_t *state)
+place_color(state_t *state, kd_forest_t *kdf, unsigned int i)
{
- // Make the forest
- kd_forest_t kdf;
- kdf_init(&kdf);
+ if (state->iteration % state->update_interval == 0) {
+ if (state->options->animate) {
+ char filename[strlen(state->options->filename) + 10];
+ sprintf(filename, "%s/%04u.png", state->options->filename, state->frame);
+ write_png(state, filename);
+ ++state->frame;
+ }
- bool animate = state->options->animate;
- unsigned int frame = 0;
- char filename[strlen(state->options->filename) + 10];
+ print_progress("%.2f%%\t| boundary size: %zu\t| max boundary size: %zu",
+ 100.0*state->iteration/state->options->ncolors, kdf->size, state->max_boundary);
+ }
- size_t max_size = 0;
- unsigned int update_interval = 1U << (state->options->bit_depth + 1)/2;
+ uint32_t color = state->colors[i];
- // Do multiple passes to get rid of artifacts in HUE_SORT mode
- unsigned int bit_depth = state->options->bit_depth;
- for (unsigned int i = 1, progress = 0; i <= bit_depth + 1; ++i) {
- unsigned int stripe = 1 << i;
+ double target[KD_DIMEN];
+ switch (state->options->color_space) {
+ case COLOR_SPACE_RGB:
+ color_set_RGB(target, color);
+ break;
+ case COLOR_SPACE_LAB:
+ color_set_Lab(target, color);
+ break;
+ case COLOR_SPACE_LUV:
+ color_set_Luv(target, color);
+ break;
+ }
- for (unsigned int j = stripe/2 - 1; j < state->options->ncolors; j += stripe, ++progress) {
- if (progress % update_interval == 0) {
- if (animate) {
- sprintf(filename, "%s/%04u.png", state->options->filename, frame);
- write_png(state, filename);
- ++frame;
- }
+ pixel_t *pixel;
+ if (state->iteration == 0) {
+ pixel = get_pixel(state, state->options->x, state->options->y);
+ } else {
+ pixel = find_next_pixel(state, kdf, target);
+ }
- print_progress("%.2f%%\t| boundary size: %zu\t| max boundary size: %zu",
- 100.0*progress/state->options->ncolors, kdf.size, max_size);
- }
+ memcpy(pixel->value, target, sizeof(target));
+ insert_new_pixel(state, kdf, pixel);
+ if (kdf->size > state->max_boundary) {
+ state->max_boundary = kdf->size;
+ }
- uint32_t color = state->colors[j];
-
- double target[KD_DIMEN];
- switch (state->options->color_space) {
- case COLOR_SPACE_RGB:
- color_set_RGB(target, color);
- break;
- case COLOR_SPACE_LAB:
- color_set_Lab(target, color);
- break;
- case COLOR_SPACE_LUV:
- color_set_Luv(target, color);
- break;
- }
+ png_byte *png_pixel = state->bitmap[pixel->y] + 4*pixel->x;
+ color_unpack(png_pixel, color);
+ png_pixel[3] = 0xFF;
+}
- pixel_t *pixel;
- if (j == 0) {
- pixel = get_pixel(state, state->options->x, state->options->y);
- } else {
- pixel = find_next_pixel(state, &kdf, target);
- }
+static void
+generate_bitmap(state_t *state)
+{
+ // Make the forest
+ kd_forest_t kdf;
+ kdf_init(&kdf);
- memcpy(pixel->value, target, sizeof(target));
- insert_new_pixel(state, &kdf, pixel);
- if (kdf.size > max_size) {
- max_size = kdf.size;
+ if (state->options->stripe) {
+ for (unsigned int i = 1; i <= state->options->bit_depth + 1; ++i) {
+ unsigned int stripe = 1 << i;
+ for (unsigned int j = stripe/2 - 1; j < state->options->ncolors; j += stripe, ++state->iteration) {
+ place_color(state, &kdf, j);
}
-
- png_byte *png_pixel = state->bitmap[pixel->y] + 4*pixel->x;
- color_unpack(png_pixel, color);
- png_pixel[3] = 0xFF;
+ }
+ } else {
+ for (unsigned int i = 0; i < state->options->ncolors; ++i, ++state->iteration) {
+ place_color(state, &kdf, i);
}
}
- if (animate) {
+ if (state->options->animate) {
+ char filename[strlen(state->options->filename) + 10];
+
#if __unix__
sprintf(filename, "%s/last.png", state->options->filename);
write_png(state, filename);
for (int i = 0; i < 120; ++i) {
- sprintf(filename, "%s/%04u.png", state->options->filename, frame + i);
+ sprintf(filename, "%s/%04u.png", state->options->filename, state->frame + i);
if (symlink("last.png", filename) != 0) {
abort();
}
}
#else
for (int i = 0; i < 120; ++i) {
- sprintf(filename, "%s/%04u.png", state->options->filename, frame + i);
+ sprintf(filename, "%s/%04u.png", state->options->filename, state->frame + i);
write_png(state, filename);
}
#endif
}
print_progress("%.2f%%\t| boundary size: %zu\t| max boundary size: %zu\n",
- 100.0, kdf.size, max_size);
+ 100.0, kdf.size, state->max_boundary);
kdf_destroy(&kdf);
}