summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LICENSE15
-rw-r--r--Makefile47
-rw-r--r--arg.h63
-rw-r--r--config.mk14
-rw-r--r--imagefile2png.c87
-rw-r--r--png2imagefile.c75
6 files changed, 301 insertions, 0 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..6abc946
--- /dev/null
+++ 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
new file mode 100644
index 0000000..de4f4bd
--- /dev/null
+++ 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
new file mode 100644
index 0000000..4df77a7
--- /dev/null
+++ 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
new file mode 100644
index 0000000..7a698d9
--- /dev/null
+++ 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
new file mode 100644
index 0000000..cb170ff
--- /dev/null
+++ 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
new file mode 100644
index 0000000..17e0b52
--- /dev/null
+++ 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;
+}