// Displays popi generated images on Plan9 4th/ed.
// Popi information can be found at:
// http://cm.bell-labs.com/cm/cs/who/gerard/
//
// bugs are mine fst@centurytel.net
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>
#include <bio.h>
#define DEF_X 248 /* image width */
#define DEF_Y 248 /* image height */
// Thresholds for halftone conversion from 8bit grayscale
// See "Beyond Photography, The digital Darkroom", G.J. Holtzmann
#define RES 8
uchar threshold[RES][RES] = {
{ 0,128,32,160,8,136,40,168},
{ 192,64,224,96,200,72,232,104 },
{ 48,176,16,144,56,184,24,152 },
{ 240,112,208,80,248,120,216,88 },
{ 12,140,44,172,4,132,36,164 },
{ 204,76,236,108,196,68,228,100 },
{ 60,188,28,156,52,180,20,148 },
{ 252,124,220,92,244,116,212,84 }
};
void usage(void)
{
fprint(2, "usage: disp [-h] imagefile\n");
fprint(2, "\timagefile is generated by popi\n");
exits("usage");
}
void eresized(int x)
{
}
int main(int argc, char **argv)
{
Biobufhdr *infile;
int nr, hflag = 0;
uchar g8[DEF_Y * DEF_X]; /* grey scale buffer */
uchar g1[DEF_Y * DEF_X/8]; /* halftone buffer, 1 bit per pixel*/
Image *dpic;
Event ev;
Rectangle r, R = Rect(0,0,DEF_X,DEF_Y);
ARGBEGIN {
case 'h': /* halftone display */
hflag = 1;
break;
default:
usage();
} ARGEND
if (argc < 1) {
fprint(2, "imagefile missing\n");
usage();
}
if (! (infile = Bopen(argv[0], OREAD))) {
fprint(2, "can't open %s: %r\n", argv[0]);
usage();
}
initdraw(nil, nil, "disp");
einit(Ekeyboard|Emouse);
dpic = allocimage(display, R, (hflag) ? GREY1 : GREY8, 1, DWhite);
/* popi image files are DEF_Y×DEF_X×8bit grayscale pixels */
nr = DEF_Y * DEF_X;
if (Bread(infile, g8, nr) != nr) {
fprint(2, "bad popi image file\n");
usage();
}
if (hflag) { /* halftone conversion */
int y, x;
memset(g1, 0, sizeof(g1));
for (y = 0; y < DEF_Y; y++) {
for (x = 0; x < DEF_X; x++) {
int graypixloc = y * (DEF_Y) + x;
int bwpixbyte = y * (DEF_Y/8) + x/8;
if (g8[graypixloc] > threshold[y%RES][x%RES])
g1[bwpixbyte] |= 0x80 >> x%8;
}
}
}
loadimage(dpic, R, (hflag) ? g1 : g8, nr);
r = Rpt(screen->r.min, addpt(screen->r.min, Pt(DEF_X,DEF_Y)));
draw(screen, r, dpic, nil, Pt(0,0));
while(event(&ev) != Ekeyboard)
;
exits(0);
}
|