colors

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

commit ef981559f89ef9cca302a0ea2c01a70e1f88fa78
parent 237ea2d686b03726093197df4f644832da2ae695
Author: sin <sin@2f30.org>
Date:   Thu Jun  4 15:17:20 +0100

Factor out image parsing

Diffstat:
Makefile | 5+++--
colors.c | 105+++++++++++++++++++++----------------------------------------------------------
colors.h | 2++
png.c | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 100 insertions(+), 80 deletions(-)
diff --git a/Makefile b/Makefile @@ -3,7 +3,7 @@ VERSION = 0.1 PREFIX = /usr/local LDFLAGS = -lm -lpng CFLAGS = -Wall -O3 -OBJ = colors.o +OBJ = colors.o png.o BIN = colors all: $(BIN) @@ -11,7 +11,8 @@ all: $(BIN) $(BIN): $(OBJ) $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(OBJ) $(LDFLAGS) -colors.o: arg.h queue.h +colors.o: arg.h colors.h queue.h +png.o: arg.h colors.h queue.h clean: rm -f $(BIN) $(OBJ) diff --git a/colors.c b/colors.c @@ -6,8 +6,8 @@ #include <stdio.h> #include <stdlib.h> #include <time.h> -#include <png.h> #include "arg.h" +#include "colors.h" #include "queue.h" struct point { @@ -29,17 +29,6 @@ TAILQ_HEAD(points, point) points; size_t npoints; int eflag; -void * -emalloc(size_t n) -{ - void *p; - - p = malloc(n); - if (!p) - err(1, "malloc"); - return p; -} - int distance(struct point *p1, struct point *p2) { @@ -101,7 +90,9 @@ initclusters(struct cluster *c, size_t n) { size_t i; - clusters = emalloc(sizeof(*clusters) * n); + clusters = malloc(sizeof(*clusters) * n); + if (!clusters) + err(1, "malloc"); for (i = 0; i < n; i++) initcluster(&clusters[i]); } @@ -134,7 +125,10 @@ process(void) struct point *p, *tmp; int *dists, mind, mini, i, done = 0; - dists = emalloc(nclusters * sizeof(*dists)); + dists = malloc(nclusters * sizeof(*dists)); + if (!dists) + err(1, "malloc"); + while (!done) { done = 1; TAILQ_FOREACH_SAFE(p, &points, e, tmp) { @@ -170,7 +164,23 @@ process(void) } void -printcolors(void) +fillpoints(int r, int g, int b) +{ + struct point *p; + + p = malloc(sizeof(*p)); + if (!p) + err(1, "malloc"); + p->x = r; + p->y = g; + p->z = b; + p->c = NULL; + TAILQ_INSERT_TAIL(&points, p, e); + npoints++; +} + +void +printclusters(void) { int i; @@ -183,67 +193,6 @@ printcolors(void) } void -initpoints(char *f) -{ - FILE *fp; - png_structp png_ptr; - png_infop info_ptr; - png_byte hdr[8]; - png_bytep *rows; - int width, height; - int x, y; - - if (!(fp = fopen(f, "r"))) - err(1, "fopen %s", f); - fread(hdr, 1, 8, fp); - if (png_sig_cmp(hdr, 0, 8)) - errx(1, "not a png file"); - - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - info_ptr = png_create_info_struct(png_ptr); - if (!png_ptr || !info_ptr || setjmp(png_jmpbuf(png_ptr))) - errx(1, "failed to initialize libpng"); - - png_init_io(png_ptr, fp); - png_set_add_alpha(png_ptr, 255, PNG_FILLER_AFTER); - png_set_gray_to_rgb(png_ptr); - png_set_sig_bytes(png_ptr, 8); - png_read_info(png_ptr, info_ptr); - - width = png_get_image_width(png_ptr, info_ptr); - height = png_get_image_height(png_ptr, info_ptr); - png_read_update_info(png_ptr, info_ptr); - - if (setjmp(png_jmpbuf(png_ptr))) - errx(1, "failed to read image"); - - rows = emalloc(sizeof(*rows) * height); - for (y = 0; y < height; y++) - rows[y] = emalloc(png_get_rowbytes(png_ptr, info_ptr)); - png_read_image(png_ptr, rows); - - for (y = 0; y < height; y++) { - png_byte *row = rows[y]; - for (x = 0; x < width; x++) { - png_byte *p = &row[x * 4]; - struct point *newp = emalloc(sizeof(*newp)); - newp->x = p[0]; - newp->y = p[1]; - newp->z = p[2]; - newp->c = NULL; - TAILQ_INSERT_TAIL(&points, newp, e); - npoints++; - } - } - - for (y = 0; y < height; y++) - free(rows[y]); - free(rows); - - fclose(fp); -} - -void usage(void) { fprintf(stderr, "usage: %s [-n clusters] [-e] png-file\n", argv0); @@ -276,9 +225,9 @@ main(int argc, char *argv[]) srand(time(NULL)); TAILQ_INIT(&points); - initpoints(argv[0]); + parseimg(argv[0], fillpoints); initclusters(clusters, nclusters); process(); - printcolors(); + printclusters(); return 0; } diff --git a/colors.h b/colors.h @@ -0,0 +1,2 @@ +/* See LICENSE file for copyright and license details. */ +void parseimg(char *, void (*)(int, int, int)); diff --git a/png.c b/png.c @@ -0,0 +1,68 @@ +/* See LICENSE file for copyright and license details. */ +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <png.h> +#include "colors.h" + +void +parseimg(char *f, void (*fn)(int, int, int)) +{ + FILE *fp; + png_structp png_ptr; + png_infop info_ptr; + png_byte hdr[8]; + png_bytep *rows; + int width, height; + int x, y; + + if (!(fp = fopen(f, "r"))) + err(1, "fopen %s", f); + fread(hdr, 1, 8, fp); + if (png_sig_cmp(hdr, 0, 8)) + errx(1, "not a png file"); + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + info_ptr = png_create_info_struct(png_ptr); + if (!png_ptr || !info_ptr || setjmp(png_jmpbuf(png_ptr))) + errx(1, "failed to initialize libpng"); + + png_init_io(png_ptr, fp); + png_set_add_alpha(png_ptr, 255, PNG_FILLER_AFTER); + png_set_gray_to_rgb(png_ptr); + png_set_sig_bytes(png_ptr, 8); + png_read_info(png_ptr, info_ptr); + + width = png_get_image_width(png_ptr, info_ptr); + height = png_get_image_height(png_ptr, info_ptr); + png_read_update_info(png_ptr, info_ptr); + + if (setjmp(png_jmpbuf(png_ptr))) + errx(1, "failed to read image"); + + rows = malloc(sizeof(*rows) * height); + if (!rows) + err(1, "malloc"); + for (y = 0; y < height; y++) { + rows[y] = malloc(png_get_rowbytes(png_ptr, info_ptr)); + if (!rows[y]) + err(1, "malloc"); + } + + png_read_image(png_ptr, rows); + + for (y = 0; y < height; y++) { + png_byte *row = rows[y]; + for (x = 0; x < width; x++) { + png_byte *p = &row[x * 4]; + fn(p[0], p[1], p[2]); + } + } + + for (y = 0; y < height; y++) + free(rows[y]); + free(rows); + + fclose(fp); + +}