[hackers] [PATCH] [sent] Quick patch to replace png with farbfeld

From: Dimitris Papastamos <sin_AT_2f30.org>
Date: Tue, 17 Nov 2015 15:01:40 +0000

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
_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..3d85d6f 100644
--- a/README.md
+++ b/README.md
_AT_@ -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
_AT_@ -29,18 +29,17 @@ presentation file could look like this:
 
         sent
         
- _AT_nyan.png
+ _AT_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
         
- \_AT_FILE.png
+ \_AT_FILE.ff
         
         thanks / questions?
 
_AT_@ -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
_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..51ec822 100644
--- a/example
+++ b/example
_AT_@ -12,7 +12,7 @@ also:
 terminal presentations
 don't support images…
 
-_AT_nyan.png
+_AT_nyan.ff
 this text will not be displayed, since the _AT_ at the start of the first line
 makes this paragraph an image slide.
 
_AT_@ -20,7 +20,6 @@ easy to use
 
 depends on
 ♽ Xlib
-☢ libpng
 
 ~1000 lines of code
 
_AT_@ -29,7 +28,7 @@ $ sent FILE1 [FILE2 …]
 
 ▸ one slide per paragraph
 ▸ lines starting with # are ignored
-▸ image slide: paragraph containing _AT_FILE.png
+▸ image slide: paragraph containing _AT_FILE.ff
 ▸ empty slide: just use a \ as a paragraph
 
 # This is a comment and will not be part of the presentation
_AT_@ -45,7 +44,7 @@ $ sent FILE1 [FILE2 …]
 \
 \
 
-\_AT_this_line_actually_started_with_a_\.png
+\_AT_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
_AT_@ -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>
_AT_@ -37,8 +38,6 @@ typedef struct {
         imgstate state;
         XImage *ximg;
         FILE *f;
- png_structp png_ptr;
- png_infop info_ptr;
         int numpasses;
 } Image;
 
_AT_@ -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();
_AT_@ -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"))) {
_AT_@ -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;
_AT_@ -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;
_AT_@ -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;
_AT_@ -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;
_AT_@ -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;
_AT_@ -447,7 +414,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 +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]);
         }
 }
_AT_@ -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);
         }
 }
 
Received on Tue Nov 17 2015 - 16:01:40 CET

This archive was generated by hypermail 2.3.0 : Tue Nov 17 2015 - 16:12:16 CET