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