[hackers] [slock][PATCH] Reset color to INIT on Escape key press

2016-04-03 Thread Thomas
This is so people who have the INIT color set to black but the FAILURE
color set to something else can still have their monitor black out after
failing to unlock, without having to unlock and lock again.

Also makes sense because pushing Esc isn't really a failure, but a
purposefully aborted unlock attempt, so the background shouldn't be set
to FAILURE.

(Note: let me know if you prefer to pull from Github, I'm new to the
list.)
---
 slock.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/slock.c b/slock.c
index c9cdee2..48f917f 100644
--- a/slock.c
+++ b/slock.c
@@ -125,6 +125,7 @@ readpw(Display *dpy, const char *pws)
KeySym ksym;
XEvent ev;
static int oldc = INIT;
+   Bool reset = False;
 
len = 0;
running = True;
@@ -165,6 +166,7 @@ readpw(Display *dpy, const char *pws)
break;
case XK_Escape:
len = 0;
+   reset = True;
break;
case XK_BackSpace:
if (len)
@@ -177,7 +179,12 @@ readpw(Display *dpy, const char *pws)
}
break;
}
-   color = len ? INPUT : (failure || failonclear ? FAILED 
: INIT);
+   if (reset) {
+   color = INIT;
+   reset = False;
+   } else {
+   color = len ? INPUT : (failure || failonclear ? 
FAILED : INIT);
+   }
if (running && oldc != color) {
for (screen = 0; screen < nscreens; screen++) {
XSetWindowBackground(dpy, 
locks[screen]->win, locks[screen]->colors[color]);
-- 
2.8.0




Re:Re: [hackers] [dmenu][PATCH] history navigation

2016-04-03 Thread crispyf...@163.com
Thanks,  I'll do it.



-phi

At 2016-04-04 02:59:44, "Anselm R Garbe"  wrote:
>On 3 April 2016 at 05:35, crispyf...@163.com  wrote:
>> This patch provides the ability for history navigation similar to that of
>> bash. Press alt+p for the previous history  and alt+n for the next. Set the
>> maximum number of histories with a new variable 'maxhist' in config.h. By
>> default, it only records a new history if it is not the same as the last
>> one. To change this behaviour, set 'histnodup' to 0 in config.h.
>> I hope it is useful for someone.
>
>If you want better visibility of your patch, please add it to the wiki[0].
>
>[0] http://suckless.org/wiki
>
>BR,
>-Anselm
>


Re: [hackers] [sbase][PATCH] grep: remove = flag from readme

2016-04-03 Thread Mattias Andrée
It works on musl.

On Sun, 3 Apr 2016 14:59:37 -0700
Eric Pruitt  wrote:

> On Sun, Apr 03, 2016 at 11:57:25PM +0200, Mattias Andrée
> wrote:
> > > On Sun, Apr 03, 2016 at 11:50:08PM +0200, Mattias
> > > Andrée wrote:  
> > > > That works with musl but not glibc.  
> > >
> > > If you use 'setlocale(LC_ALL, "")' with GCC, grep
> > > behaves as expected:  
> >
> > I assume you mean glibc. Does that work on musl too?  
> 
> Sorry, yes; I meant glibc. I don't know if it works with
> musl because I don't have it configured on this machine.
> 
> Eric



pgp7q0NV5CQJn.pgp
Description: OpenPGP digital signature


Re: [hackers] [sbase][PATCH] grep: remove = flag from readme

2016-04-03 Thread Eric Pruitt
On Sun, Apr 03, 2016 at 11:57:25PM +0200, Mattias Andrée wrote:
> > On Sun, Apr 03, 2016 at 11:50:08PM +0200, Mattias Andrée
> > wrote:
> > > That works with musl but not glibc.
> >
> > If you use 'setlocale(LC_ALL, "")' with GCC, grep behaves
> > as expected:
>
> I assume you mean glibc. Does that work on musl too?

Sorry, yes; I meant glibc. I don't know if it works with musl because I
don't have it configured on this machine.

Eric



Re: [hackers] [sbase][PATCH] grep: remove = flag from readme

2016-04-03 Thread Mattias Andrée
On Sun, 3 Apr 2016 14:55:35 -0700
Eric Pruitt  wrote:

> On Sun, Apr 03, 2016 at 11:50:08PM +0200, Mattias Andrée
> wrote:
> > That works with musl but not glibc.  
> 
> If you use 'setlocale(LC_ALL, "")' with GCC, grep behaves
> as expected:

I assume you mean glibc. Does that work on musl too?

> 
> sbase$ echo äö | ./grep '[å]'
> (1)
> sbase$ echo å | ./grep '[å]'
> å
> 
> Eric
> 



pgpqn_MFG7OQR.pgp
Description: OpenPGP digital signature


Re: [hackers] [sbase][PATCH] grep: remove = flag from readme

2016-04-03 Thread Eric Pruitt
On Sun, Apr 03, 2016 at 11:50:08PM +0200, Mattias Andrée wrote:
> That works with musl but not glibc.

If you use 'setlocale(LC_ALL, "")' with GCC, grep behaves as expected:

sbase$ echo äö | ./grep '[å]'
(1)
sbase$ echo å | ./grep '[å]'
å

Eric



Re: [hackers] [sbase][PATCH] grep: remove = flag from readme

2016-04-03 Thread Mattias Andrée
That works with musl but not glibc.

On Sun, 3 Apr 2016 23:39:38 +0200
FRIGN  wrote:

> On Sun, 3 Apr 2016 23:35:21 +0200
> Mattias Andrée  wrote:
> 
> Hey Mattias,
> 
> > Perhaps it could be noted. But it fails
> > with both musl and glibc. I think we need new
> > regex engine, perhaps adapted from musl,
> > that supports NUL bytes and UTF-8 transparently.  
> 
> you could also try a
> 
>   setlocale(LC_ALL, "UTF-8");
> 
> in grep(1). Maybe that works.
> 
> Cheers
> 
> FRIGN
> 



pgpkO4sDifqIk.pgp
Description: OpenPGP digital signature


Re: [hackers] [sbase][PATCH] grep: remove = flag from readme

2016-04-03 Thread FRIGN
On Sun, 3 Apr 2016 23:35:21 +0200
Mattias Andrée  wrote:

Hey Mattias,

> Perhaps it could be noted. But it fails
> with both musl and glibc. I think we need new
> regex engine, perhaps adapted from musl,
> that supports NUL bytes and UTF-8 transparently.

you could also try a

setlocale(LC_ALL, "UTF-8");

in grep(1). Maybe that works.

Cheers

FRIGN

-- 
FRIGN 



Re: [hackers] [sbase][PATCH] grep: add -r

2016-04-03 Thread Mattias Andrée
On Sun, 3 Apr 2016 22:31:30 +0200
FRIGN  wrote:

> On Wed, 30 Mar 2016 05:23:08 +0200
> Mattias Andrée  wrote:
> 
> > Unlike your usual grep -r, this implementation
> > uses breadth-first search. It usually finds
> > makes it find what you are looking for faster.  
> 
> Try working with recurse() in libutil.

Of course. what was I thinking...

> 
> Cheers
> 
> FRIGN
> 



pgpXzuQ4LyqYk.pgp
Description: OpenPGP digital signature


Re: [hackers] [sbase][PATCH] grep: remove = flag from readme

2016-04-03 Thread Mattias Andrée
Perhaps it could be noted. But it fails
with both musl and glibc. I think we need new
regex engine, perhaps adapted from musl,
that supports NUL bytes and UTF-8 transparently.

maandree

On Sun, 3 Apr 2016 22:30:45 +0200
FRIGN  wrote:

> On Wed, 30 Mar 2016 19:01:16 +0200
> Mattias Andrée  wrote:
> 
> Hey Mattias,
> 
> >   $ echo äö | ./grep [å]
> >   äö
> > 
> > This is not want one expects from
> > a program that supports UTF-8.  
> 
> I assume the proper way here would be to add a note on
> the manpage that this highly depends on the libc you are
> using (and esp. the Regex engine).
> 
> Cheers
> 
> FRIGN
> 



pgpBloNgHUxcG.pgp
Description: OpenPGP digital signature


Re: [hackers] [sbase][PATCH] grep: add -r

2016-04-03 Thread FRIGN
On Wed, 30 Mar 2016 05:23:08 +0200
Mattias Andrée  wrote:

> Unlike your usual grep -r, this implementation
> uses breadth-first search. It usually finds
> makes it find what you are looking for faster.

Try working with recurse() in libutil.

Cheers

FRIGN

-- 
FRIGN 



Re: [hackers] [sbase][PATCH] grep: remove = flag from readme

2016-04-03 Thread FRIGN
On Wed, 30 Mar 2016 19:01:16 +0200
Mattias Andrée  wrote:

Hey Mattias,

>   $ echo äö | ./grep [å]
>   äö
> 
> This is not want one expects from
> a program that supports UTF-8.

I assume the proper way here would be to add a note on the manpage that
this highly depends on the libc you are using (and esp. the Regex engine).

Cheers

FRIGN

-- 
FRIGN 



[hackers] [farbfeld] Remove line-breaks from Makefile || FRIGN

2016-04-03 Thread git
commit d8796e33f347b92a6526a1f3e6da8f5ddae7391b
Author: FRIGN 
AuthorDate: Sun Apr 3 22:17:33 2016 +0200
Commit: FRIGN 
CommitDate: Sun Apr 3 22:17:33 2016 +0200

Remove line-breaks from Makefile

Even though I like line-length limits, it imposed a useless limitation
on the console output, given the line input is variable.

diff --git a/Makefile b/Makefile
index c108e25..21b82d9 100644
--- a/Makefile
+++ b/Makefile
@@ -12,12 +12,10 @@ MAN5 = farbfeld.5
 all: ${BIN}
 
 png2ff ff2png:
-   ${CC} -o $@ ${CFLAGS} ${CPPFLAGS} -L${PNGLIB} -lpng -I${PNGINC} \
-   ${LDFLAGS} $@.c
+   ${CC} -o $@ ${CFLAGS} ${CPPFLAGS} -L${PNGLIB} -lpng -I${PNGINC} 
${LDFLAGS} $@.c
 
 jpg2ff ff2jpg:
-   ${CC} -o $@ ${CFLAGS} ${CPPFLAGS} -L${JPGLIB} -ljpeg -I${JPGINC} \
-   ${LDFLAGS} $@.c
+   ${CC} -o $@ ${CFLAGS} ${CPPFLAGS} -L${JPGLIB} -ljpeg -I${JPGINC} 
${LDFLAGS} $@.c
 
 .c:
${CC} -o $@ ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} $<
@@ -28,10 +26,8 @@ clean:
 dist:
rm -rf "farbfeld-${VERSION}"
mkdir -p "farbfeld-${VERSION}"
-   cp -R FORMAT LICENSE Makefile README TODO config.mk \
-   ${SCRIPTS} ${HDR} ${SRC} ${MAN1} ${MAN5} "farbfeld-${VERSION}"
-   tar -cf - "farbfeld-${VERSION}" | \
-   gzip -c > "farbfeld-${VERSION}.tar.gz"
+   cp -R FORMAT LICENSE Makefile README TODO config.mk ${SCRIPTS} ${HDR} 
${SRC} ${MAN1} ${MAN5} "farbfeld-${VERSION}"
+   tar -cf - "farbfeld-${VERSION}" | gzip -c > "farbfeld-${VERSION}.tar.gz"
rm -rf "farbfeld-${VERSION}"
 
 install: all



[hackers] [farbfeld] Makefile improvements || Hiltjo Posthuma

2016-04-03 Thread git
commit 47a5f38ce9d44b5c3c0dad9e7824c8e2156a203d
Author: Hiltjo Posthuma 
AuthorDate: Sun Apr 3 21:44:20 2016 +0200
Commit: FRIGN 
CommitDate: Sun Apr 3 22:07:12 2016 +0200

Makefile improvements

- be verbose by default: don't hide the executed commands.
- no need to make clean on make dist, but make sure to have a clean 
directory.
- define 2ff in ${SCRIPTS}.
- make dist: gzip directly, don't store intermediate step (faster for make 
dist
  on floppies).
- don't cd into directories, just loop each file.

diff --git a/Makefile b/Makefile
index 865e87b..c108e25 100644
--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,7 @@
 include config.mk
 
 BIN = png2ff ff2png jpg2ff ff2jpg ff2ppm
+SCRIPTS = 2ff
 SRC = ${BIN:=.c}
 HDR = arg.h
 MAN1 = 2ff.1 ${BIN:=.1}
@@ -11,49 +12,42 @@ MAN5 = farbfeld.5
 all: ${BIN}
 
 png2ff ff2png:
-   @echo CC $@
-   @${CC} -o $@ ${CFLAGS} ${CPPFLAGS} -L${PNGLIB} -lpng -I${PNGINC} \
+   ${CC} -o $@ ${CFLAGS} ${CPPFLAGS} -L${PNGLIB} -lpng -I${PNGINC} \
${LDFLAGS} $@.c
 
 jpg2ff ff2jpg:
-   @echo CC $@
-   @${CC} -o $@ ${CFLAGS} ${CPPFLAGS} -L${JPGLIB} -ljpeg -I${JPGINC} \
+   ${CC} -o $@ ${CFLAGS} ${CPPFLAGS} -L${JPGLIB} -ljpeg -I${JPGINC} \
${LDFLAGS} $@.c
 
 .c:
-   @echo CC $@
-   @${CC} -o $@ ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} $<
+   ${CC} -o $@ ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} $<
 
 clean:
-   @echo cleaning
-   @rm -f ${BIN}
-
-dist: clean
-   @echo creating dist tarball
-   @mkdir -p farbfeld-${VERSION}
-   @cp -R FORMAT LICENSE Makefile README TODO config.mk \
-   2ff ${HDR} ${SRC} ${MAN1} ${MAN5} farbfeld-${VERSION}
-   @tar -cf farbfeld-${VERSION}.tar farbfeld-${VERSION}
-   @gzip farbfeld-${VERSION}.tar
-   @rm -rf farbfeld-${VERSION}
+   rm -f ${BIN}
+
+dist:
+   rm -rf "farbfeld-${VERSION}"
+   mkdir -p "farbfeld-${VERSION}"
+   cp -R FORMAT LICENSE Makefile README TODO config.mk \
+   ${SCRIPTS} ${HDR} ${SRC} ${MAN1} ${MAN5} "farbfeld-${VERSION}"
+   tar -cf - "farbfeld-${VERSION}" | \
+   gzip -c > "farbfeld-${VERSION}.tar.gz"
+   rm -rf "farbfeld-${VERSION}"
 
 install: all
-   @echo installing into ${DESTDIR}${PREFIX}/bin
-   @mkdir -p "${DESTDIR}${PREFIX}/bin"
-   @cp -f 2ff ${BIN} "${DESTDIR}${PREFIX}/bin"
-   @echo installing manpages into ${DESTDIR}${MANPREFIX}
-   @mkdir -p "${DESTDIR}${MANPREFIX}/man1"
-   @cp -f ${MAN1} "${DESTDIR}${MANPREFIX}/man1"
-   @cd "${DESTDIR}${MANPREFIX}/man1" && chmod 644 ${MAN1}
-   @mkdir -p "${DESTDIR}${MANPREFIX}/man5"
-   @cp -f ${MAN5} "${DESTDIR}${MANPREFIX}/man5"
-   @cd "${DESTDIR}${MANPREFIX}/man5" && chmod 644 ${MAN5}
+   mkdir -p "${DESTDIR}${PREFIX}/bin"
+   cp -f ${SCRIPTS} ${BIN} "${DESTDIR}${PREFIX}/bin"
+   for f in $(BIN) $(SCRIPTS); do chmod 755 "${DESTDIR}${PREFIX}/bin/$$f"; 
done
+   mkdir -p "${DESTDIR}${MANPREFIX}/man1"
+   cp -f ${MAN1} "${DESTDIR}${MANPREFIX}/man1"
+   for m in $(MAN1); do chmod 644 "${DESTDIR}${MANPREFIX}/man1/$$m"; done
+   mkdir -p "${DESTDIR}${MANPREFIX}/man5"
+   cp -f ${MAN5} "${DESTDIR}${MANPREFIX}/man5"
+   for m in $(MAN5); do chmod 644 "${DESTDIR}${MANPREFIX}/man5/$$m"; done
 
 uninstall:
-   @echo removing from ${DESTDIR}${PREFIX}/bin
-   @cd "${DESTDIR}${PREFIX}/bin" && rm -f 2ff ${BIN}
-   @echo removing manpages from ${DESTDIR}${MANPREFIX}
-   @cd "${DESTDIR}${MANPREFIX}/man1" && rm -f ${MAN1}
-   @cd "${DESTDIR}${MANPREFIX}/man5" && rm -f ${MAN5}
+   for f in $(BIN) $(SCRIPTS); do rm -f "${DESTDIR}${PREFIX}/bin/$$f"; done
+   for m in $(MAN1); do rm -f "${DESTDIR}${MANPREFIX}/man1/$$m"; done
+   for m in $(MAN5); do rm -f "${DESTDIR}${MANPREFIX}/man5/$$m"; done
 
 .PHONY: all clean dist install uninstall



Re: [hackers] [dmenu][PATCH] history navigation

2016-04-03 Thread Anselm R Garbe
On 3 April 2016 at 05:35, crispyf...@163.com  wrote:
> This patch provides the ability for history navigation similar to that of
> bash. Press alt+p for the previous history  and alt+n for the next. Set the
> maximum number of histories with a new variable 'maxhist' in config.h. By
> default, it only records a new history if it is not the same as the last
> one. To change this behaviour, set 'histnodup' to 0 in config.h.
> I hope it is useful for someone.

If you want better visibility of your patch, please add it to the wiki[0].

[0] http://suckless.org/wiki

BR,
-Anselm



[hackers] [farbfeld] don't link against unneeded libs || Hiltjo Posthuma

2016-04-03 Thread git
commit 7f295f8c100a504c305d537bd3fde6492f15ef7a
Author: Hiltjo Posthuma 
AuthorDate: Thu Mar 24 19:09:41 2016 +0100
Commit: FRIGN 
CommitDate: Sun Apr 3 20:39:13 2016 +0200

don't link against unneeded libs

- jpg2ff requires libjpeg
- ff2png, png2ff requires libpng (and libz)
- ff2ppm has no dependencies

diff --git a/Makefile b/Makefile
index 63b4d0a..ac85a0f 100644
--- a/Makefile
+++ b/Makefile
@@ -8,11 +8,21 @@ HDR = arg.h
 MAN1 = 2ff.1 ${BIN:=.1}
 MAN5 = farbfeld.5
 
-all: png2ff ff2png jpg2ff ff2ppm
+all: ${BIN}
+
+png2ff ff2png:
+   @echo CC $@
+   @${CC} -o $@ ${CFLAGS} ${CPPFLAGS} -L${PNGLIB} -lpng -I${PNGINC} \
+   ${LDFLAGS} $@.c
+
+jpg2ff:
+   @echo CC $@
+   @${CC} -o $@ ${CFLAGS} ${CPPFLAGS} -L${JPGLIB} -ljpeg -I${JPGINC} \
+   ${LDFLAGS} $@.c
 
 .c:
-   @echo CC $<
-   @${CC} -o $@ ${CFLAGS} ${LIBS} ${LDFLAGS} $<
+   @echo CC $@
+   @${CC} -o $@ ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} $<
 
 clean:
@echo cleaning
diff --git a/config.mk b/config.mk
index 94a4570..4ecba54 100644
--- a/config.mk
+++ b/config.mk
@@ -13,12 +13,12 @@ PNGINC = /usr/local/include
 JPGLIB = /usr/local/lib
 JPGINC = /usr/local/include
 
-INCS = -I${PNGINC} -I${JPGINC}
-LIBS = -L${PNGLIB} -L${JPGLIB} -lpng -ljpeg
+INCS =
+LIBS =
 
 # flags
 CPPFLAGS = -D_DEFAULT_SOURCE
-CFLAGS   = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
+CFLAGS   = -std=c99 -pedantic -Wall -Os ${INCS}
 LDFLAGS  = -s ${LIBS}
 
 # compiler and linker



[hackers] [farbfeld] fix bugs introduced by refactor f0a4ce113d0e9dc50110a0ad9e98433d05aa2307 || Hiltjo Posthuma

2016-04-03 Thread git
commit 264979bf52261cb461212be8978c2a4697aa2e80
Author: Hiltjo Posthuma 
AuthorDate: Thu Mar 24 18:45:57 2016 +0100
Commit: FRIGN 
CommitDate: Sun Apr 3 20:39:13 2016 +0200

fix bugs introduced by refactor f0a4ce113d0e9dc50110a0ad9e98433d05aa2307

diff --git a/ff2ppm.c b/ff2ppm.c
index 6ff4416..83b059e 100644
--- a/ff2ppm.c
+++ b/ff2ppm.c
@@ -41,7 +41,7 @@ main(int argc, char *argv[])
if (collen != 3 && collen != 6 && collen != 12) {
usage();
}
-   colfmt[1] = colfmt[4] = colfmt[7] = ((collen / 3) - '0');
+   colfmt[1] = colfmt[4] = colfmt[7] = ((collen / 3) + '0');
if (sscanf(color, colfmt, col, col + 1, col + 2) != 3) {
usage();
}
@@ -50,6 +50,7 @@ main(int argc, char *argv[])
for (i = 0; i < 3; i++) {
mask[i] = col[i] * colfac;
}
+   break;
default:
usage();
} ARGEND



[hackers] [farbfeld] add ff2jpg tool, convert farbfeld images to RGB JPEG || Hiltjo Posthuma

2016-04-03 Thread git
commit 34e9cba51f5149da0670b32101e23b4d76e20d61
Author: Hiltjo Posthuma 
AuthorDate: Thu Mar 24 19:17:48 2016 +0100
Commit: FRIGN 
CommitDate: Sun Apr 3 20:39:13 2016 +0200

add ff2jpg tool, convert farbfeld images to RGB JPEG

diff --git a/LICENSE b/LICENSE
index 04a34f5..fdc6d84 100644
--- a/LICENSE
+++ b/LICENSE
@@ -15,5 +15,5 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 
ARISING OUT OF
 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 (c) 2014-2015 Dimitris Papastamos 
-(c) 2014-2015 Hiltjo Posthuma 
+(c) 2014-2016 Hiltjo Posthuma 
 (c) 2015 Willy Goiffon 
diff --git a/Makefile b/Makefile
index ac85a0f..865e87b 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 # See LICENSE file for copyright and license details
 include config.mk
 
-BIN = png2ff ff2png jpg2ff ff2ppm
+BIN = png2ff ff2png jpg2ff ff2jpg ff2ppm
 SRC = ${BIN:=.c}
 HDR = arg.h
 MAN1 = 2ff.1 ${BIN:=.1}
@@ -15,7 +15,7 @@ png2ff ff2png:
@${CC} -o $@ ${CFLAGS} ${CPPFLAGS} -L${PNGLIB} -lpng -I${PNGINC} \
${LDFLAGS} $@.c
 
-jpg2ff:
+jpg2ff ff2jpg:
@echo CC $@
@${CC} -o $@ ${CFLAGS} ${CPPFLAGS} -L${JPGLIB} -ljpeg -I${JPGINC} \
${LDFLAGS} $@.c
diff --git a/ff2jpg.1 b/ff2jpg.1
new file mode 100644
index 000..d202988
--- /dev/null
+++ b/ff2jpg.1
@@ -0,0 +1,56 @@
+.Dd 2016-03-23
+.Dt FF2JPG 1
+.Os suckless.org
+.Sh NAME
+.Nm ff2jpg
+.Nd convert farbfeld to JPEG
+.Sh SYNOPSIS
+.Nm
+.Op Fl b Ar color
+.Op Fl o
+.Op Fl q Ar quality
+.Sh DESCRIPTION
+.Nm
+reads a
+.Xr farbfeld 5
+image from stdin, converts it to a JPEG image (RGB) and writes the result to
+stdout.
+.Pp
+In case of an error
+.Nm
+writes a diagnostic message to stderr.
+.Sh OPTIONS
+.Bl -tag -width Ds
+.It Fl b Ar color
+.Ar color
+to mix with the background alpha channel, the default is white.
+.Pp
+The following formats are supported:
+"#rrggbb", "#" and the short-form "#rgb" which expands to 
"#rrggbb".
+.It Fl o
+Optimize Huffman table (smaller file, but slow compression).
+.It Fl q Ar quality
+set JPEG output
+.Ar quality
+(range 0-100), the default is 85.
+.El
+.Sh EXIT STATUS
+.Bl -tag -width Ds
+.It 0
+Image processed successfully.
+.It 1
+An error occurred.
+.El
+.Sh EXAMPLES
+$
+png2ff < test.png |
+.Nm
+-b '#00ff00' -q 85 > test.jpg
+.Sh SEE ALSO
+.Xr 2ff 1 ,
+.Xr bunzip2 1 ,
+.Xr bzip2 1 ,
+.Xr png2ff 1 ,
+.Xr farbfeld 5
+.Sh AUTHORS
+.An Hiltjo Posthuma Aq Mt hil...@codemadness.org
diff --git a/ff2jpg.c b/ff2jpg.c
new file mode 100644
index 000..d489774
--- /dev/null
+++ b/ff2jpg.c
@@ -0,0 +1,151 @@
+/* See LICENSE file for copyright and license details. */
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "arg.h"
+
+char *argv0;
+
+METHODDEF(void)
+jpeg_error(j_common_ptr js)
+{
+   fprintf(stderr, "%s: libjpeg: ", argv0);
+   (*js->err->output_message)(js);
+   exit(1);
+}
+
+static void
+usage(void)
+{
+   fprintf(stderr, "usage: %s [-b #rrggbb] [-o] [-q quality]\n", argv0);
+   exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+   JSAMPROW row_pointer[1]; /* pointer to a single row */
+   struct jpeg_compress_struct cinfo;
+   struct jpeg_error_mgr jerr;
+   size_t rowlen;
+   uint64_t a;
+   uint32_t hdr[4], width, height, i, j, k, l;
+   uint16_t *row, mask[3] = { 0x, 0x, 0x };
+   uint8_t *rowout;
+   char *color, colfmt[] = "%#x%#x%#x";
+   unsigned int collen, col[3], colfac, quality = 85, optimize = 0;
+
+   argv0 = argv[0];
+   ARGBEGIN {
+   case 'b':
+   color = EARGF(usage());
+   if (color[0] == '#') {
+   color++;
+   }
+   collen = strlen(color);
+   if (collen != 3 && collen != 6 && collen != 12) {
+   usage();
+   }
+   colfmt[1] = colfmt[4] = colfmt[7] = ((collen / 3) + '0');
+   if (sscanf(color, colfmt, col, col + 1, col + 2) != 3) {
+   usage();
+   }
+   /* UINT16_MAX / 255 = 257; UINT16_MAX / 15 = 4369 */
+   colfac = (collen == 3) ? 4369 : (collen == 6) ? 257 : 1;
+   for (i = 0; i < 3; i++) {
+   mask[i] = col[i] * colfac;
+   }
+   break;
+   case 'o':
+   optimize = 1;
+   break;
+   case 'q':
+   if ((quality = atoi(EARGF(usage( > 100)
+   usage();
+   break;
+   default:
+   usage();
+   } ARGEND
+
+   if (argc)
+   usage();
+
+   /* header */
+   if (fread(hdr, sizeof(*hdr), 4, stdin) != 4) {
+   fprintf(stderr, "%s: fread: %s\n", argv0, strerror(errno));
+   return 1;
+   }
+   if (memcmp("farbfeld", hdr, sizeof("farbfeld") - 1)) {
+   fprintf(stderr, "%s: invalid magic value\n"