farbfeld

suckless image format with conversion tools
git clone git://git.suckless.org/farbfeld
Log | Files | Refs | README | LICENSE

commit c7507e64d03aa8fcfe225880abc37a42028a40e1
Author: FRIGN <dev@frign.de>
Date:   Sat, 19 Jul 2014 21:35:34 +0100

Initial commit

Diffstat:
ALICENSE | 15+++++++++++++++
AMakefile | 47+++++++++++++++++++++++++++++++++++++++++++++++
Aarg.h | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aconfig.mk | 14++++++++++++++
Aimagefile2png.c | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apng2imagefile.c | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 301 insertions(+), 0 deletions(-)

diff --git a/LICENSE b/LICENSE @@ -0,0 +1,15 @@ +ISC-License + +(c) 2014 Laslo Hunhold <dev@frign.de> + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/Makefile b/Makefile @@ -0,0 +1,47 @@ +# imagefile - tools to convert to imagefile and back +# See LICENSE file for copyright and license details + +include config.mk + +SRC = png2imagefile.c imagefile2png.c +OBJ = ${SRC:.c=.o} + +all: options png2imagefile imagefile2png + +options: + @echo imagefile build options: + @echo "CFLAGS = ${CFLAGS}" + @echo "LDFLAGS = ${LDFLAGS}" + @echo "CC = ${CC}" + +.c.o: + @echo CC $< + @${CC} -c -o $@ ${CFLAGS} $< + +${OBJ}: config.mk + +png2imagefile: png2imagefile.o + @echo CC -o $@ + @${CC} -o $@ png2imagefile.o ${LDFLAGS} + +imagefile2png: imagefile2png.o + @echo CC -o $@ + @${CC} -o $@ imagefile2png.o ${LDFLAGS} + +clean: + @echo cleaning + @rm -f png2imagefile imagefile2png ${OBJ} + +install: all + @echo installing executable files to ${DESTDIR}${PREFIX}/bin + @mkdir -p ${DESTDIR}${PREFIX}/bin + @cp -f png2imagefile imagefile2png ${DESTDIR}${PREFIX}/bin + @chmod 755 ${DESTDIR}${PREFIX}/bin/png2imagefile + @chmod 755 ${DESTDIR}${PREFIX}/bin/imagefile2png + +uninstall: + @echo removing executable files from ${DESTDIR}${PREFIX}/bin + @rm -f ${DESTDIR}${PREFIX}/bin/png2imagefile + @rm -f ${DESTDIR}${PREFIX}/bin/imagefile2png + +.PHONY: all options clean install uninstall diff --git a/arg.h b/arg.h @@ -0,0 +1,63 @@ +/* + * Copy me if you can. + * by 20h + */ + +#ifndef ARG_H__ +#define ARG_H__ + +extern char *argv0; + +/* use main(int argc, char *argv[]) */ +#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\ + argv[0] && argv[0][1]\ + && argv[0][0] == '-';\ + argc--, argv++) {\ + char argc_;\ + char **argv_;\ + int brk_;\ + if (argv[0][1] == '-' && argv[0][2] == '\0') {\ + argv++;\ + argc--;\ + break;\ + }\ + for (brk_ = 0, argv[0]++, argv_ = argv;\ + argv[0][0] && !brk_;\ + argv[0]++) {\ + if (argv_ != argv)\ + break;\ + argc_ = argv[0][0];\ + switch (argc_) + +/* Handles obsolete -NUM syntax */ +#define ARGNUM case '0':\ + case '1':\ + case '2':\ + case '3':\ + case '4':\ + case '5':\ + case '6':\ + case '7':\ + case '8':\ + case '9' + +#define ARGEND }\ + } + +#define ARGC() argc_ + +#define ARGNUMF(base) (brk_ = 1, estrtol(argv[0], (base))) + +#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\ + ((x), abort(), (char *)0) :\ + (brk_ = 1, (argv[0][1] != '\0')?\ + (&argv[0][1]) :\ + (argc--, argv++, argv[0]))) + +#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\ + (char *)0 :\ + (brk_ = 1, (argv[0][1] != '\0')?\ + (&argv[0][1]) :\ + (argc--, argv++, argv[0]))) + +#endif diff --git a/config.mk b/config.mk @@ -0,0 +1,14 @@ +# Customize below to fit your system + +# paths +PREFIX = /usr/local + +# libs +LIBS = -lpng + +# flags +CFLAGS = -std=c90 -pedantic -ansi -Wall -Wextra -Wno-pointer-sign -Wno-maybe-uninitialized -Os +LDFLAGS = -s ${LIBS} + +# compiler and linker +CC = cc diff --git a/imagefile2png.c b/imagefile2png.c @@ -0,0 +1,87 @@ +/* See LICENSE file for copyright and license details. */ +#include <arpa/inet.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include "arg.h" +#include <png.h> + +char *argv0; + +#define HEADER_FORMAT "imagefile########" + +static void +usage(void) +{ + fprintf(stderr, "usage: %s\n", argv0); + exit(EXIT_FAILURE); +} + +int +main(int argc, char *argv[]) +{ + png_structp png_struct_p; + png_infop png_info_p; + uint8_t hdr[17], *png_row; + uint32_t width, height, png_row_len, i; + + ARGBEGIN { + default: + usage(); + } ARGEND; + + if (argc != 0) + usage(); + + /* header */ + if (fread(hdr, 1, strlen(HEADER_FORMAT), stdin) != strlen(HEADER_FORMAT)) { + fprintf(stderr, "failed to read from stdin or input too short\n"); + goto err; + } + if (strcmp("imagefile", hdr)) { + fprintf(stderr, "invalid header\n"); + goto err; + } + width = ntohl((hdr[9] << 0) | (hdr[10] << 8) | (hdr[11] << 16) | (hdr[12] << 24)); + height = ntohl((hdr[13] << 0) | (hdr[14] << 8) | (hdr[15] << 16) | (hdr[16] << 24)); + + /* load png */ + png_struct_p = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + png_info_p = png_create_info_struct(png_struct_p); + + if (!png_struct_p || !png_info_p || setjmp(png_jmpbuf(png_struct_p))) { + fprintf(stderr, "failed to initialize libpng\n"); + goto err; + } + png_init_io(png_struct_p, stdout); + png_set_IHDR(png_struct_p, png_info_p, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + png_write_info(png_struct_p, png_info_p); + + /* write rows */ + png_row_len = strlen("RGBA") * width * sizeof(uint8_t); + png_row = malloc(png_row_len); + + for (i=0; i < height; ++i) { + if (fread(png_row, 1, png_row_len, stdin) != png_row_len) { + fprintf(stderr, "unexpected EOF or row-skew at %d\n", i); + goto err; + } + png_write_row(png_struct_p, png_row); + } + png_write_end(png_struct_p, NULL); + + /* clean up */ + png_free_data(png_struct_p, png_info_p, PNG_FREE_ALL, -1); + png_destroy_write_struct(&png_struct_p, NULL); + free(png_row); + return EXIT_SUCCESS; +err: + png_free_data(png_struct_p, png_info_p, PNG_FREE_ALL, -1); + png_destroy_write_struct(&png_struct_p, NULL); + free(png_row); + return EXIT_FAILURE; +} diff --git a/png2imagefile.c b/png2imagefile.c @@ -0,0 +1,75 @@ +/* See LICENSE file for copyright and license details. */ +#include <arpa/inet.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include "arg.h" +#include <png.h> + +char *argv0; + +static void +usage(void) +{ + fprintf(stderr, "usage: %s\n", argv0); + exit(EXIT_FAILURE); +} + +int +main(int argc, char *argv[]) +{ + png_structp png_struct_p; + png_infop png_info_p; + png_bytepp png_row_p; + uint32_t width, height, val_be, depth, color, interlace, png_row_len, r; + + ARGBEGIN { + default: + usage(); + } ARGEND; + + if (argc != 0) + usage(); + + /* load png */ + png_struct_p = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + png_info_p = png_create_info_struct(png_struct_p); + + if (!png_struct_p || !png_info_p || setjmp(png_jmpbuf(png_struct_p))) { + fprintf(stderr, "failed to initialize libpng"); + goto err; + } + png_init_io(png_struct_p, stdin); + png_set_add_alpha(png_struct_p, 255, PNG_FILLER_AFTER); + png_read_png(png_struct_p, png_info_p, PNG_TRANSFORM_STRIP_16 | + PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND , NULL); + png_get_IHDR(png_struct_p, png_info_p, &width, &height, &depth, + &color, &interlace, NULL, NULL); + png_row_len = png_get_rowbytes(png_struct_p, png_info_p); + png_row_p = png_get_rows(png_struct_p, png_info_p); + + /* write header with big endian width and height-values */ + fprintf(stdout, "imagefile"); + val_be = htonl(width); + fwrite(&val_be, sizeof(uint32_t), 1, stdout); + val_be = htonl(height); + fwrite(&val_be, sizeof(uint32_t), 1, stdout); + + /* write data */ + for (r = 0; r < height; ++r) { + if (fwrite(png_row_p[r], 1, (size_t)png_row_len, stdout) != png_row_len) { + fprintf(stderr, "fwrite() failed\n"); + goto err; + } + } + + /* clean up */ + png_destroy_read_struct(&png_struct_p, &png_info_p, NULL); + return EXIT_SUCCESS; +err: + png_destroy_read_struct(&png_struct_p, &png_info_p, NULL); + return EXIT_FAILURE; +}