Hi,

Very quick and dirty patch.  This is intended to generate a discussion
on the applicability of farbfeld in sent.  I can polish the patch
later depending on the outcome of the discussion.

diff --git a/LICENSE b/LICENSE
index d1da8fc..8d5665e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -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..3d85d6f 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 sent is a simple plaintext presentation tool.
 
 sent does not need latex, libreoffice or any other fancy file format, it uses
-plaintext files and png images. Every paragraph represents a slide in the
+plaintext files and farbfeld[0] images. Every paragraph represents a slide in 
the
 presentation.
 
 The presentation is displayed in a simple X11 window. The content of each slide
@@ -29,18 +29,17 @@ presentation file could look like this:
 
        sent
        
-       @nyan.png
+       @nyan.ff
        
        depends on
        - Xlib
-       - libpng
        
        sent FILENAME
        one slide per paragraph
        # This is a comment and will not be part of the presentation
        \# This and the next line start with backslashes
        
-       \@FILE.png
+       \@FILE.ff
        
        thanks / questions?
 
@@ -48,3 +47,5 @@ presentation file could look like this:
 Development
 
 sent is developed at http://tools.suckless.org/sent
+
+[0] http://git.2f30.org/farbfeld/
diff --git a/config.mk b/config.mk
index ed08199..52d5fb1 100644
--- a/config.mk
+++ b/config.mk
@@ -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..51ec822 100644
--- a/example
+++ b/example
@@ -12,7 +12,7 @@ also:
 terminal presentations
 don't support images…
 
-@nyan.png
+@nyan.ff
 this text will not be displayed, since the @ at the start of the first line
 makes this paragraph an image slide.
 
@@ -20,7 +20,6 @@ easy to use
 
 depends on
 ♽ Xlib
-☢ libpng
 
 ~1000 lines of code
 
@@ -29,7 +28,7 @@ $ sent FILE1 [FILE2 …]
 
 ▸ one slide per paragraph
 ▸ lines starting with # are ignored
-▸ image slide: paragraph containing @FILE.png
+▸ image slide: paragraph containing @FILE.ff
 ▸ empty slide: just use a \ as a paragraph
 
 # This is a comment and will not be part of the presentation
@@ -45,7 +44,7 @@ $ sent FILE1 [FILE2 …]
 \
 \
 
-\@this_line_actually_started_with_a_\.png
+\@this_line_actually_started_with_a_\.ff
 \#This line as well
 ⇒ Prepend a backslash to kill behaviour of special characters
 
diff --git a/nyan.png b/nyan.png
deleted file mode 100644
index 377b9d0..0000000
Binary files a/nyan.png and /dev/null differ
diff --git a/sent.c b/sent.c
index 4e2e810..bcdbf51 100644
--- a/sent.c
+++ b/sent.c
@@ -1,7 +1,8 @@
 /* See LICENSE for licence details. */
+#include <arpa/inet.h>
+
 #include <errno.h>
 #include <math.h>
-#include <png.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdint.h>
@@ -37,8 +38,6 @@ typedef struct {
        imgstate state;
        XImage *ximg;
        FILE *f;
-       png_structp png_ptr;
-       png_infop info_ptr;
        int numpasses;
 } Image;
 
@@ -79,12 +78,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();
@@ -128,10 +127,10 @@ static void (*handler[LASTEvent])(XEvent *) = {
        [KeyPress] = kpress,
 };
 
-Image *pngopen(char *filename)
+Image *ffopen(char *filename)
 {
        FILE *f;
-       unsigned char buf[8];
+       unsigned char hdr[16];
        Image *img;
 
        if (!(f = fopen(filename, "rb"))) {
@@ -139,45 +138,33 @@ Image *pngopen(char *filename)
                return NULL;
        }
 
-       if (fread(buf, 1, 8, f) != 8 || png_sig_cmp(buf, 1, 8))
+       if (fread(hdr, 1, 16, f) != 16)
                return NULL;
 
-       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);
-               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 = calloc(1, sizeof(Image));
        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->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;
 
        if (!img)
                return 0;
@@ -187,59 +174,39 @@ 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);
                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++) {
+               if (fread(row, 1, rowlen, img->f) != rowlen) {
+                       free(row);
+                       free(img->buf);
+                       return 0;
+               }
+               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);
+       free(row);
        fclose(img->f);
        img->state |= LOADED;
 
        return 1;
 }
 
-int pngprepare(Image *img)
+int ffprepare(Image *img)
 {
        int depth = DefaultDepth(xw.dpy, xw.scr);
        int width = xw.uw;
@@ -276,12 +243,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;
@@ -306,7 +273,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;
@@ -364,7 +331,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;
@@ -447,7 +414,7 @@ void load(FILE *fp)
                        /* only make image slide if first line of a slide 
starts with @ */
                        if (s->linecount == 0 && s->lines[0][0] == '@') {
                                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] == '\\')
@@ -469,9 +436,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]);
        }
 }
@@ -536,12 +503,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);
        }
 }
 

Reply via email to