colors

extract colors from pictures
git clone git://git.2f30.org/colors
Log | Files | Refs | README | LICENSE

commit 0986303c82c50be80b1dcf3ecb2d11ec0598dff1
parent 4f006c77769ed7a7c2a2a771192ca1a1e44abe90
Author: sin <sin@2f30.org>
Date:   Wed, 10 Jun 2015 17:35:22 +0100

Switch to vector based representation for points

Diffstat:
MMakefile | 7++++---
Mcolors.c | 24++++++++++++------------
Avector.c | 48++++++++++++++++++++++++++++++++++++++++++++++++
Avector.h | 14++++++++++++++
4 files changed, 78 insertions(+), 15 deletions(-)

diff --git a/Makefile b/Makefile @@ -6,7 +6,7 @@ MANPREFIX = $(PREFIX)/man CPPFLAGS = -I/usr/local/include CFLAGS = -Wall -O3 LDFLAGS = -L/usr/local/lib -lpng -OBJ = colors.o png.o +OBJ = colors.o png.o vector.o BIN = colors all: $(BIN) @@ -14,8 +14,9 @@ all: $(BIN) $(BIN): $(OBJ) $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(OBJ) $(LDFLAGS) -colors.o: arg.h colors.h queue.h -png.o: arg.h colors.h queue.h +colors.o: arg.h colors.h queue.h vector.h +png.o: colors.h +vector.o: vector.h install: all mkdir -p $(DESTDIR)$(PREFIX)/bin diff --git a/colors.c b/colors.c @@ -9,6 +9,7 @@ #include "arg.h" #include "colors.h" #include "queue.h" +#include "vector.h" #define LEN(x) (sizeof (x) / sizeof *(x)) @@ -25,10 +26,11 @@ struct cluster { }; char *argv0; + struct cluster *clusters; size_t nclusters = 8; -TAILQ_HEAD(points, point) points; -size_t npoints; +struct vector points; + int eflag; int rflag; int hflag; @@ -159,9 +161,7 @@ initcluster_pixel(struct cluster *c, int i) TAILQ_INIT(&c->members); c->nmembers = 0; - TAILQ_FOREACH(p, &points, e) - if (i-- == 0) - break; + p = vector_get(&points, i); c->center = *p; } @@ -253,8 +253,8 @@ hasmember(struct cluster *c, struct point *p) void process(void) { - struct point *p, *tmp; - int *dists, mind, mini, i, done = 0; + struct point *p; + int *dists, mind, mini, i, j, done = 0; dists = malloc(nclusters * sizeof(*dists)); if (!dists) @@ -262,7 +262,8 @@ process(void) while (!done) { done = 1; - TAILQ_FOREACH_SAFE(p, &points, e, tmp) { + for (j = 0; j < vector_size(&points); j++) { + p = vector_get(&points, j); for (i = 0; i < nclusters; i++) dists[i] = distance(p, &clusters[i].center); @@ -305,8 +306,7 @@ fillpoints(int r, int g, int b) p->y = g; p->z = b; p->c = NULL; - TAILQ_INSERT_TAIL(&points, p, e); - npoints++; + vector_add(&points, p); } void @@ -365,7 +365,7 @@ main(int argc, char *argv[]) if (argc != 1) usage(); - TAILQ_INIT(&points); + vector_init(&points); parseimg(argv[0], fillpoints); if (mflag) @@ -374,7 +374,7 @@ main(int argc, char *argv[]) srand(time(NULL)); if (pflag) { initcluster = initcluster_pixel; - initspace = npoints; + initspace = vector_size(&points); } if (hflag) { initcluster = initcluster_hue; diff --git a/vector.c b/vector.c @@ -0,0 +1,48 @@ +#include <err.h> +#include <stdlib.h> + +#include "vector.h" + +static void +grow(struct vector *v) +{ + if (v->s >= v->c) { + v->c = !v->c ? 1 : v->c * 2; + v->d = realloc(v->d, sizeof(*v->d) * v->c); + if (!v->d) + err(1, "realloc"); + } +} + +void +vector_init(struct vector *v) +{ + v->s = 0; + v->c = 0; + v->d = NULL; +} + +void +vector_free(struct vector *v) +{ + free(v->d); +} + +void +vector_add(struct vector *v, void *data) +{ + grow(v); + v->d[v->s++].raw = data; +} + +void * +vector_get(struct vector *v, size_t i) +{ + return v->d[i].raw; +} + +size_t +vector_size(struct vector *v) +{ + return v->s; +} diff --git a/vector.h b/vector.h @@ -0,0 +1,14 @@ +struct vector_data { + void *raw; +}; + +struct vector { + struct vector_data *d; + size_t c; + size_t s; +}; + +void vector_init(struct vector *); +void vector_add(struct vector *, void *); +void *vector_get(struct vector *, size_t); +size_t vector_size(struct vector *);