--- LICENSE | 2 - README.md | 1 - config.def.h | 5 ++ config.mk | 2 +- example | 1 - sent.c | 196 +++++++++++++++++++++++++++++++++-------------------------- 6 files changed, 115 insertions(+), 92 deletions(-) diff --git a/LICENSE b/LICENSE index d1da8fc..8d5665e 100644 --- a/LICENSE +++ b/LICENSE _AT_@ -2,8 +2,6 @@ The MIT License (MIT) Copyright (c) 2014-2015 Markus Teich -png handling stuff adapted from meh by John Hawthorn - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights diff --git a/README.md b/README.md index 007564b..e213efb 100644 --- a/README.md +++ b/README.md _AT_@ -33,7 +33,6 @@ presentation file could look like this: depends on - Xlib - - libpng sent FILENAME one slide per paragraph diff --git a/config.def.h b/config.def.h index 6ecc267..4c6f2d0 100644 --- a/config.def.h +++ b/config.def.h _AT_@ -40,3 +40,8 @@ static Shortcut shortcuts[] = { { XK_Next, advance, {.i = +1} }, { XK_Prior, advance, {.i = -1} }, }; + +static Filter filters[] = { + { "\\.png$", "png2ff" }, + { "\\.(jpg|gif)$", "2ff" }, +}; diff --git a/config.mk b/config.mk index ed08199..52d5fb1 100644 --- a/config.mk +++ b/config.mk _AT_@ -12,7 +12,7 @@ X11LIB = /usr/X11R6/lib # includes and libs INCS = -I. -I/usr/include -I/usr/include/freetype2 -I${X11INC} -LIBS = -L/usr/lib -lc -lm -L${X11LIB} -lXft -lfontconfig -lX11 -lpng +LIBS = -L/usr/lib -lc -lm -L${X11LIB} -lXft -lfontconfig -lX11 # flags CPPFLAGS = -DVERSION=\"${VERSION}\" -D_XOPEN_SOURCE=600 diff --git a/example b/example index 39e0206..d4b62d2 100644 --- a/example +++ b/example _AT_@ -20,7 +20,6 @@ easy to use depends on ♽ Xlib -☢ libpng ~1000 lines of code diff --git a/sent.c b/sent.c index 4e2e810..aa1fc71 100644 --- a/sent.c +++ b/sent.c _AT_@ -1,12 +1,17 @@ /* See LICENSE for licence details. */ +#include <sys/types.h> +#include <arpa/inet.h> + #include <errno.h> +#include <fcntl.h> #include <math.h> -#include <png.h> +#include <regex.h> #include <stdarg.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> #include <X11/keysym.h> #include <X11/XKBlib.h> #include <X11/Xatom.h> _AT_@ -36,13 +41,16 @@ typedef struct { unsigned int bufwidth, bufheight; imgstate state; XImage *ximg; - FILE *f; - png_structp png_ptr; - png_infop info_ptr; + int fd; int numpasses; } Image; typedef struct { + char *regex; + char *bin; +} Filter; + +typedef struct { unsigned int linecount; char **lines; Image *img; _AT_@ -79,12 +87,12 @@ typedef struct { const Arg arg; } Shortcut; -static Image *pngopen(char *filename); -static void pngfree(Image *img); -static int pngread(Image *img); -static int pngprepare(Image *img); -static void pngscale(Image *img); -static void pngdraw(Image *img); +static Image *ffopen(char *filename); +static void fffree(Image *img); +static int ffread(Image *img); +static int ffprepare(Image *img); +static void ffscale(Image *img); +static void ffdraw(Image *img); static void getfontsize(Slide *s, unsigned int *width, unsigned int *height); static void cleanup(); _AT_@ -128,56 +136,87 @@ static void (*handler[LASTEvent])(XEvent *) = { [KeyPress] = kpress, }; -Image *pngopen(char *filename) +int +filter(int fd, const char *cmd) +{ + int fds[2]; + + if (pipe(fds) < 0) + eprintf("pipe:"); + + switch (fork()) { + case -1: + eprintf("fork:"); + case 0: + dup2(fd, 0); + dup2(fds[1], 1); + close(fds[0]); + close(fds[1]); + execlp(cmd, cmd, (char *)0); + eprintf("execlp %s:", cmd); + } + close(fds[1]); + return fds[0]; +} + +Image *ffopen(char *filename) { - FILE *f; - unsigned char buf[8]; + unsigned char hdr[16]; + char *bin; + regex_t regex; Image *img; + size_t i; + int tmpfd, fd; + + for (bin = NULL, i = 0; i < LEN(filters); i++) { + if (regcomp(®ex, filters[i].regex, + REG_NOSUB | REG_EXTENDED | REG_ICASE)) + continue; + if (!regexec(®ex, filename, 0, NULL, 0)) { + bin = filters[i].bin; + break; + } + } - if (!(f = fopen(filename, "rb"))) { + if ((fd = open(filename, O_RDONLY)) < 0) { eprintf("could not open file %s:", filename); return NULL; } - if (fread(buf, 1, 8, f) != 8 || png_sig_cmp(buf, 1, 8)) - return NULL; + tmpfd = fd; + fd = filter(fd, bin); + if (fd < 0) + eprintf("could not filter %s:", filename); + close(tmpfd); - img = malloc(sizeof(Image)); - memset(img, 0, sizeof(Image)); - if (!(img->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, - NULL, NULL))) { - free(img); + if (read(fd, hdr, 16) != 16) return NULL; - } - if (!(img->info_ptr = png_create_info_struct(img->png_ptr)) - || setjmp(png_jmpbuf(img->png_ptr))) { - pngfree(img); + + if (memcmp("farbfeld", hdr, 8)) return NULL; - } - img->f = f; - rewind(f); - png_init_io(img->png_ptr, f); - png_read_info(img->png_ptr, img->info_ptr); - img->bufwidth = png_get_image_width(img->png_ptr, img->info_ptr); - img->bufheight = png_get_image_height(img->png_ptr, img->info_ptr); + img = calloc(1, sizeof(Image)); + img->fd = fd; + img->bufwidth = ntohl(*(uint32_t *)&hdr[8]); + img->bufheight = ntohl(*(uint32_t *)&hdr[12]); return img; } -void pngfree(Image *img) +void fffree(Image *img) { - png_destroy_read_struct(&img->png_ptr, img->info_ptr ? &img->info_ptr : NULL, NULL); free(img->buf); if (img->ximg) XDestroyImage(img->ximg); free(img); } -int pngread(Image *img) +int ffread(Image *img) { - unsigned int y; - png_bytepp row_pointers; + uint32_t y, x; + uint16_t *row; + size_t rowlen, off, nbytes; + ssize_t r; if (!img) return 0; _AT_@ -187,59 +226,42 @@ int pngread(Image *img) if (img->buf) free(img->buf); + /* internally the image is stored in 888 format */ if (!(img->buf = malloc(3 * img->bufwidth * img->bufheight))) return 0; - if (setjmp(png_jmpbuf(img->png_ptr))) { - png_destroy_read_struct(&img->png_ptr, &img->info_ptr, NULL); + /* scratch buffer to read row by row */ + rowlen = img->bufwidth * 2 * strlen("RGBA"); + row = malloc(rowlen); + if (!row) { + free(img->buf); + img->buf = NULL; return 0; } - { - int color_type = png_get_color_type(img->png_ptr, img->info_ptr); - int bit_depth = png_get_bit_depth(img->png_ptr, img->info_ptr); - if (color_type == PNG_COLOR_TYPE_PALETTE) - png_set_expand(img->png_ptr); - if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) - png_set_expand(img->png_ptr); - if (png_get_valid(img->png_ptr, img->info_ptr, PNG_INFO_tRNS)) - png_set_expand(img->png_ptr); - if (bit_depth == 16) - png_set_strip_16(img->png_ptr); - if (color_type == PNG_COLOR_TYPE_GRAY - || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - png_set_gray_to_rgb(img->png_ptr); - - png_color_16 my_background = {.red = 0xff, .green = 0xff, .blue = 0xff}; - png_color_16p image_background; - - if (png_get_bKGD(img->png_ptr, img->info_ptr, &image_background)) - png_set_background(img->png_ptr, image_background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); - else - png_set_background(img->png_ptr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 2, 1.0); - - if (png_get_interlace_type(img->png_ptr, img->info_ptr) == PNG_INTERLACE_ADAM7) - img->numpasses = png_set_interlace_handling(img->png_ptr); - else - img->numpasses = 1; - png_read_update_info(img->png_ptr, img->info_ptr); + for (off = 0, y = 0; y < img->bufheight; y++) { + nbytes = 0; + while (nbytes < rowlen) { + r = read(img->fd, (char *)row + nbytes, rowlen - nbytes); + if (r < 0) + eprintf("read:"); + nbytes += r; + } + for (x = 0; x < rowlen / 2; x += 4) { + img->buf[off++] = ntohs(row[x + 0]) / 257; + img->buf[off++] = ntohs(row[x + 1]) / 257; + img->buf[off++] = ntohs(row[x + 2]) / 257; + } } - row_pointers = (png_bytepp)malloc(img->bufheight * sizeof(png_bytep)); - for (y = 0; y < img->bufheight; y++) - row_pointers[y] = img->buf + y * img->bufwidth * 3; - - png_read_image(img->png_ptr, row_pointers); - free(row_pointers); - - png_destroy_read_struct(&img->png_ptr, &img->info_ptr, NULL); - fclose(img->f); + free(row); + close(img->fd); img->state |= LOADED; return 1; } -int pngprepare(Image *img) +int ffprepare(Image *img) { int depth = DefaultDepth(xw.dpy, xw.scr); int width = xw.uw; _AT_@ -276,12 +298,12 @@ int pngprepare(Image *img) return 0; } - pngscale(img); + ffscale(img); img->state |= SCALED; return 1; } -void pngscale(Image *img) +void ffscale(Image *img) { unsigned int x, y; unsigned int width = img->ximg->width; _AT_@ -306,7 +328,7 @@ void pngscale(Image *img) } } -void pngdraw(Image *img) +void ffdraw(Image *img) { int xoffset = (xw.w - img->ximg->width) / 2; int yoffset = (xw.h - img->ximg->height) / 2; _AT_@ -364,7 +386,7 @@ void cleanup() free(slides[i].lines[j]); free(slides[i].lines); if (slides[i].img) - pngfree(slides[i].img); + fffree(slides[i].img); } free(slides); slides = NULL; _AT_@ -447,7 +469,7 @@ void load(FILE *fp) /* only make image slide if first line of a slide starts with _AT_ */ if (s->linecount == 0 && s->lines[0][0] == '_AT_') { memmove(s->lines[0], &s->lines[0][1], blen); - s->img = pngopen(s->lines[0]); + s->img = ffopen(s->lines[0]); } if (s->lines[s->linecount][0] == '\\') _AT_@ -469,9 +491,9 @@ void advance(const Arg *arg) slides[idx].img->state &= ~(DRAWN | SCALED); idx = new_idx; xdraw(); - if (slidecount > idx + 1 && slides[idx + 1].img && !pngread(slides[idx + 1].img)) + if (slidecount > idx + 1 && slides[idx + 1].img && !ffread(slides[idx + 1].img)) die("could not read image %s", slides[idx + 1].lines[0]); - if (0 < idx && slides[idx - 1].img && !pngread(slides[idx - 1].img)) + if (0 < idx && slides[idx - 1].img && !ffread(slides[idx - 1].img)) die("could not read image %s", slides[idx - 1].lines[0]); } } _AT_@ -536,12 +558,12 @@ void xdraw() slides[idx].lines[i], 0); drw_map(d, xw.win, 0, 0, xw.w, xw.h); - } else if (!(im->state & LOADED) && !pngread(im)) { + } else if (!(im->state & LOADED) && !ffread(im)) { eprintf("could not read image %s", slides[idx].lines[0]); - } else if (!(im->state & SCALED) && !pngprepare(im)) { + } else if (!(im->state & SCALED) && !ffprepare(im)) { eprintf("could not prepare image %s for drawing", slides[idx].lines[0]); } else if (!(im->state & DRAWN)) { - pngdraw(im); + ffdraw(im); } } -- 1.8.4Received on Mon Sep 17 2001 - 00:00:00 CEST
This archive was generated by hypermail 2.3.0 : Wed Nov 18 2015 - 12:00:22 CET