[comp.graphics] showpic: a tool to show ray traced images on a SUN

ingwa@prefix.liu.se (Inge Wallin) (10/03/88)

Here is a program to show images from Mark's ray tracer on a SUN.
Unlike the previous programs with the same purpose, this one shows
the images in a window, so that you do not have to use screenload, 
and thus blank the entire screen. (Possibly this already exists
but we don't know of it.)

                        O /         \ O
-------------------------X snip snip X----------------------------
                        O \         / O
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  Makefile README showpic.1 showpic.c showpic.icon
# Wrapped by ingwa@prefix on Sun Oct  2 22:03:01 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f Makefile -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile\"
else
echo shar: Extracting \"Makefile\" \(310 characters\)
sed "s/^X//" >Makefile <<'END_OF_Makefile'
X#
X# Makefile for showpic
X#
X
X#CFLAGS = -g
XCFLAGS = -O
X
XLIBS = -lsuntool -lsunwindow -lpixrect
X
XOBJS = showpic.o
X
Xshowpic: $(OBJS)
X	$(CC) -o showpic $(CFLAGS) $(OBJS) $(LIBS)
X
Xshowpic.o: showpic.c showpic.icon
X
X
Xshar:
X	shar Makefile README showpic.1 showpic.c showpic.icon >showpic.shar
X
X
Xclean:
X	rm -f *.o core
END_OF_Makefile
if test 310 -ne `wc -c <Makefile`; then
    echo shar: \"Makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(1589 characters\)
sed "s/^X//" >README <<'END_OF_README'
X*******************************************************************
X             showpic  1.0  --  show ray traced images
X
X             by         Inge Wallin       ingwa@majestix.liu.se
X                        Jonas Yngvesson   jonas-y@joakim.liu.se
X
X             Linkoping Institute of Technology
X             Sweden
X*******************************************************************
X
XThis is the README for the showpic program. Showpic takes as input
Xan image file, generated by Mark VandeWettering's ray tracer, and 
Xdisplays it on a SUN workstation. Unlike other programs which
Xhave been posted lately, showpic shows the image in a standard 
Xsunview window.
X
XThe program is extremely simple and was developed because of the
Xlack of SUNs with colour screens at this university. (Actually,
Xthere are a few of those also, but they are out of our reach.)
XThus, there is no support for colour or gray scales in it.
X
XInstead, we have put in two half-toning algorithms, ordered dithering
Xand the Floyd-Steinberg method. There are also a choise of a number of
Xdither matrixes (currently 3) for those of you who don't like the
Xstandard one. See the manual for further details!
X
XThe gray scale conversion used was provided on comp.graphics about a
Xyear ago by Edward Falk.
X
XUnfortunately, no one of us have any great artistical talents, so the
Xicon is not very beautiful. If anybody should feel like making a nicer
Xone, we would be grateful if we could have a copy of it.
X
XPlease, send any enhancements, bug reports and fixes to us.
X
XLinkoping 2 Oct 1988
X
X                enjoy! /Inge & Jonas
END_OF_README
if test 1589 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f showpic.1 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"showpic.1\"
else
echo shar: Extracting \"showpic.1\" \(1615 characters\)
sed "s/^X//" >showpic.1 <<'END_OF_showpic.1'
X.\" Copyright 1988, Inge Wallin, Jonas Yngvesson
X.\" This program and documentation may be distributed freely for
X.\" non-commercial use only.  
X.TH SHOWPIC 1 "October 2, 1988" 1
X.UC 4 
X.SH NAME
Xshowpic \- show ray traced images on a SUN
X.SH SYNOPSIS
X\fBshowpic\fR [\fB\-u\fR]
X[\fB\-f\fR]
X[\fB\-d\fR[\fIn\fR]]
X\fB\-\fR | \fIfilename\fR
X.SH DESCRIPTION
XShowpic shows an image, generated by Mark VandeWettering's ray tracer,
Xin a sunview window. The program does not return, except when the \fB\-u\fR
Xoption is given.
X.SH OPTIONS
X.IP \fB\-u\fR
XShow program usage and exit.
X.IP \fB\-f\fR
XUse Floyd\-Steinberg for halftoning. This is the default.
X.IP \fB\-d\fIn\fR
XUse ordered dithering for halftoning. \fIn\fR is the number of the
Xdither matrix you want to use. Currently there are 3 matrixes
Xavailable so \fIn\fR has to be in the range 1 to 3. If no \fIn\fR
Xis given, the program chooses a standard dither (number 1).
X.PP
XThe options \fB\-f\fR and \fB\-d\fR are exclusive and if both are
Xpresent, the program uses the last one.
X.PP
XIf showpic sees a filename as its last argument, it tries to show
Xthat file. If a hyphen is given as the last argument, the image
Xis read from stdin. This is useful, for instance, if you want to
Xview compressed images, and use zcat to uncompress them.
X.SH AUTHOR
XInge Wallin 
X.br
XJonas Yngvesson
X.SH BUGS
XNo checks are made to see if the image is bigger than the screen.
X.PP
XIf you use the standard input feature, there is no way to stop the
Xprogram with CTRL\-C. The reason for this is not entirely clear.
X.PP
XThe program should be expanded to handle gray scales and colour 
Xscreens.
END_OF_showpic.1
if test 1615 -ne `wc -c <showpic.1`; then
    echo shar: \"showpic.1\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f showpic.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"showpic.c\"
else
echo shar: Extracting \"showpic.c\" \(7115 characters\)
sed "s/^X//" >showpic.c <<'END_OF_showpic.c'
X/*
X * showpic.c - show ray traced images on a SUN
X *
X * Copyright 1988 Inge Wallin and Jonas Yngvesson.
X *
X * Use it as you like, but don't try to sell it or use it for
X * other commercial purposes.
X */
X
X#include <stdio.h>
X#include <string.h>
X#include <suntool/sunview.h>
X#include <suntool/canvas.h>
X
X#define VERSION "1.0"
X
X#ifndef TRUE			/* is sometimes defined by sunview */
X#define TRUE   1
X#define FALSE  0
X#endif
X
X#define INFILE  0		/* input from file */
X#define STDIN   1		/* input from stdin */
X
Xextern char *malloc();
X
Xstatic Frame     frame;
Xstatic Canvas    picture_canvas;
Xstatic Pixrect   *picture;
X
X
Xtypedef struct dither {
X    int   size;
X    int   shift;
X    int   *table;
X} Dither;
X
X
Xstatic int dithmat1[8][8] = {
X    {  0, 32,  8, 40,  2, 34, 10, 42 },
X    { 48, 16, 56, 24, 50, 18, 58, 26 },
X    { 12, 44,  4, 36, 14, 46,  6, 38 },
X    { 60, 28, 52, 20, 62, 30, 54, 22 },
X    {  3, 35, 11, 43,  1, 33,  9, 41 },
X    { 51, 19, 59, 27, 49, 17, 57, 25 },
X    { 15, 47,  7, 39, 13, 45,  5, 37 },
X    { 63, 31, 55, 23, 61, 29, 53, 21 }};
X
Xstatic int dithmat2[8][8] = {
X    {  52,  44,  36, 124, 132, 140, 148, 156 },
X    {  60,   4,  28, 116, 220, 228, 236, 164 },
X    {  68,  12,  20, 108, 212, 252, 244, 172 },
X    {  76,  84,  92, 100, 204, 196, 188, 180 },
X    { 132, 140, 148, 156,  52,  44,  36, 124 },
X    { 220, 228, 236, 164,  60,   4,  28, 116 },
X    { 212, 252, 244, 172,  68,  12,  20, 108 },
X    { 204, 196, 188, 180,  76,  84,  92, 100 }};
X
Xstatic int dithmat3[4][4] = {
X    {  0,  8,  3, 11 },
X    { 12,  4, 14,  7 },
X    {  2, 10,  1,  9 },
X    { 13,  6, 15,  5 }};
X
XDither dithers[] = {
X    {8, 2, (int *) dithmat1},
X    {8, 0, (int *) dithmat2},
X    {4, 4, (int *) dithmat3},
X};
Xstatic int numdithers = sizeof(dithers) / sizeof(Dither);
X
X
Xstatic int redtab[256];		/* lookup tables for gray scale conversion */
Xstatic int greentab[256];
Xstatic int bluetab[256];
X
Xstatic char *programname;
X
X
Xvoid usage(exitstatus)
Xint   exitstatus;
X{
X    fprintf(stderr, "Usage: %s [-u] [-d[n]] [-f] - | filename\n", programname);
X    fprintf(stderr, "n between 1 and %d\n", numdithers);
X    exit(exitstatus);
X}
X
X
X
Xvoid error(message)
Xchar   *message;
X{
X    fprintf(stderr, "%s: %s\n", programname, message);
X    exit(1);
X}
X
X
X
X/* The icon */
Xstatic short icon_image[] = {
X#include "showpic.icon"
X};
XDEFINE_ICON_FROM_IMAGE(showpic_icon, icon_image);
X
X
Xvoid create_windows(infilename, width, height)
Xchar   *infilename;
Xint    width;
Xint    height;
X{
X    char   header[80];
X
X    sprintf(header, "showpic %s - %s", VERSION, infilename);
X    frame = window_create(NULL, FRAME,
X			  FRAME_LABEL,   header,
X			  FRAME_ICON,    &showpic_icon,
X			  0);
X
X    picture_canvas = window_create(frame, CANVAS,
X				   WIN_HEIGHT,  height,	   
X				   WIN_WIDTH,   width,
X				   0);
X
X    window_fit(frame);
X
X}
X
X
X
Xvoid ditherfunc(infile, dithernum, width, height)
XFILE  *infile;
Xint   dithernum;
Xint   width, height;
X{
X    int   i, j;
X    int   red, green, blue;
X    int   gray;
X    int   *dithermat;
X    int   dithersize;
X    int   dithershifts;
X
X    dithermat = dithers[dithernum].table;
X    dithersize = dithers[dithernum].size;
X    dithershifts = 8 + dithers[dithernum].shift;
X    
X    for (i = 0; i < height; i++) {
X	for (j = 0; j < width; j++) {
X	    red = getc(infile);
X	    green = getc(infile);
X	    blue = getc(infile);
X	    gray = (redtab[red] + greentab[green] + bluetab[blue]) >>
X		dithershifts;
X	    if ( gray < *(dithermat + (i % dithersize) * dithersize +
X			  (j % dithersize)) )
X		pr_put(picture, j, i, 1);
X	}
X    }
X}
X
X
X
Xvoid floydfunc(infile, width, height)
XFILE  *infile;
Xint   width;
Xint   height;
X{
X    int   i, j;
X    int   red, green, blue;
X    int   gray;
X    int   err;
X    char  *buffer1;
X    char  *buffer2;
X    char  *temp;
X
X    int   alphatab[256];
X    int   betatab[256];
X    int   gammatab[256];
X    int   deltatab[256];
X
X    buffer1 = malloc(width + 2);
X    buffer2 = malloc(width + 2);
X    if ((buffer1 == NULL) || (buffer2 == NULL)) {
X	error("Couldn't allocate buffers for error distribution.");
X    }
X
X    /* Distribute the error as follows: */
X    /*    current pixel = A[i,j]        */
X    /*    A[i,   j+1] += err*7/16       */
X    /*    A[i+1, j-1] += err*3/16       */
X    /*    A[i+1, j  ] += err*5/16       */
X    /*    A[i+1, j+1] += err*1/16       */
X    for (i = 0; i < 256; i++) {
X	alphatab[i] = ((i - 128) * 7) / 16;
X	betatab[i] =  ((i - 128) * 3) / 16;
X	gammatab[i] = ((i - 128) * 5) / 16;
X	deltatab[i] = ((i - 128) * 1) / 16;
X    }
X    
X    for (i = 0; i < width; i++) {
X	err = 0;
X	for (j = 0; j < width + 2; j++)
X	    *(buffer2 + j) = 0;
X
X	for (j = 0; j < height; j++) {
X	    red = getc(infile);
X	    green = getc(infile);
X	    blue = getc(infile);
X	    gray = ((redtab[red] + greentab[green] + bluetab[blue]) >> 8) +
X		*(buffer1 + j + 1);
X	    
X	    if (gray < 128) {
X		pr_put(picture, j, i, 1);
X		err = gray;
X	    } else {
X		err = gray - 256;
X	    }
X
X	    *(buffer1 + j + 2) += alphatab[err + 128];
X	    *(buffer2 + j )    += betatab[err + 128];
X	    *(buffer2 + j + 1) += gammatab[err + 128];
X	    *(buffer2 + j + 2) += deltatab[err + 128];
X	}
X	temp = buffer1;
X	buffer1 = buffer2;
X	buffer2 = temp;
X    }
X}
X
X
X
Xvoid main(argc, argv)
Xint   argc;
Xchar  *argv[];
X{
X    int   i, j;
X    int   width, height;
X    int   ditherflag = FALSE;
X    int   dithernum = 0;
X    int   floydflag = TRUE;
X    int   inputflag = INFILE;
X    char  *infilename;
X    FILE  *infile;
X
X    programname = argv[0];
X    for (i = 1; (i < argc) && (*argv[i] == '-'); i++) {
X	switch (*(argv[i] + 1)) {
X
X	  /* usage */
X	  case 'u':
X	    usage(0);
X	    break;		/* not reached */
X
X          /* dithering */
X	  case 'd':
X	    if (*(argv[i] + 2) != '\0') {
X		if ((*(argv[i] + 2) < '1') ||
X		    (*(argv[i] + 2) > numdithers + '0'))
X		    usage(1);
X		else
X		    dithernum = *(argv[i] + 2) - '1';
X	    }
X	    ditherflag = TRUE;
X	    floydflag = FALSE;
X	    break;
X
X	  /* Floyd-Steinberg */
X	  case 'f':
X	    ditherflag = FALSE;
X	    floydflag = TRUE;
X	    break;
X
X	  /* input from stdin */
X	  case '\0':
X	    inputflag = STDIN;
X	    break;
X	    
X	  default:
X	    usage(1);
X	}
X    }
X
X    if ((ditherflag + floydflag != 1) || /* better safe than sorry */
X	((i == argc) && (inputflag == INFILE)))
X	usage(1);
X    
X    if (inputflag == INFILE) {
X	infilename = argv[i];
X	if ((infile = fopen(infilename, "r")) == NULL) {
X	    error( "Couldn't open infile.");
X	}
X    } else {
X	infilename = "standard input";
X	infile = stdin;
X    }
X
X    if (fscanf(infile, "%d %d\n", &width, &height) != 2) {
X	error("Couldn't read image size.");
X    }
X
X    create_windows(infilename, width, height);
X    picture = mem_create(width, height, 1);
X
X    /* uses the equation  gray = 0.30*red + 0.59*green + 0.11*blue  */
X    for (i = 0; i < 256; i++) {
X	redtab[i] =    77 * i;
X	greentab[i] = 151 * i;
X	bluetab[i] =   28 * i;
X    }
X    
X    if (ditherflag) {
X	ditherfunc(infile, dithernum, width, height);
X    } else if (floydflag) {
X	floydfunc(infile, width, height);
X    }
X    fclose(infile);
X
X    pw_write(canvas_pixwin(picture_canvas), 0, 0, width, height,
X	     PIX_SRC, picture, 0, 0);
X
X    window_main_loop(frame);
X    exit(0);
X}
X
X
X
END_OF_showpic.c
if test 7115 -ne `wc -c <showpic.c`; then
    echo shar: \"showpic.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f showpic.icon -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"showpic.icon\"
else
echo shar: Extracting \"showpic.icon\" \(1933 characters\)
sed "s/^X//" >showpic.icon <<'END_OF_showpic.icon'
X/* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
X */
X	0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
X	0xC000,0x0000,0x0000,0x0003,0xC000,0x0000,0x0000,0x0003,
X	0xC000,0x0000,0x0000,0x0003,0xC000,0x0000,0x0000,0x0003,
X	0xC000,0x0000,0x0000,0x0003,0xC000,0x5000,0x0000,0x0003,
X	0xC000,0xA800,0x0000,0x0003,0xC001,0x5600,0x0000,0x0003,
X	0xC000,0xA800,0x0000,0x0003,0xC001,0x5500,0x0000,0x0003,
X	0xC000,0xA880,0x0000,0x0003,0xC002,0x5200,0x0020,0x0003,
X	0xC000,0x4400,0x0068,0x0003,0xC001,0x1115,0x0054,0x0003,
X	0xC000,0x88AA,0x88AA,0x0003,0xC000,0x2055,0x4154,0x0003,
X	0xC000,0x04C6,0xA44C,0x0003,0xC000,0x0151,0x5110,0x0003,
X	0xC000,0x0AA8,0xA888,0x0003,0xC000,0x0652,0x5620,0x0003,
X	0xC000,0x00AC,0x2840,0x0003,0xC000,0x1551,0x5510,0x0003,
X	0xC00A,0x0888,0xAA80,0x0003,0xC035,0x2622,0x5420,0x0003,
X	0xC04A,0x4A44,0xAA40,0x0003,0xC115,0x1511,0x5510,0x0003,
X	0xC08A,0x8A8A,0xA888,0x0003,0xC022,0x2555,0x5620,0x0003,
X	0xC044,0x46AA,0xAC40,0x4003,0xC010,0x1155,0x5111,0x5003,
X	0xC008,0x88AA,0xA88A,0xA803,0xC000,0x2255,0x6221,0x4003,
X	0xC000,0x444A,0x4446,0xA403,0xC000,0x1111,0x1111,0x5003,
X	0xC002,0x8888,0x8888,0x8803,0xC005,0x4222,0x1202,0x2003,
X	0xC04A,0xA444,0xAA44,0x4003,0xC085,0x5111,0x5501,0x1003,
X	0xC00A,0xA888,0xAA80,0x8003,0xC041,0x4223,0x5520,0x0003,
X	0xC204,0x8444,0xAA40,0x0003,0xC861,0x1011,0x5500,0x0003,
X	0xCE40,0x8C00,0xAA80,0x0003,0xDA02,0x2442,0x1220,0x0003,
X	0xE540,0x4004,0x4440,0x0003,0xC110,0x1151,0x1100,0x0003,
X	0xC800,0x0000,0x0000,0x0003,0xE218,0x0000,0x0000,0x0003,
X	0xC640,0x0400,0x0000,0x1003,0xD310,0x0400,0x0000,0x0003,
X	0xC889,0xC587,0x112C,0x7073,0xE222,0x2648,0x9132,0x108B,
X	0xC442,0x0448,0x9522,0x1083,0xE051,0xC448,0x9522,0x1083,
X	0xC908,0x2448,0x9522,0x1083,0xE102,0x2448,0x9532,0x108B,
X	0xC401,0xC447,0x0A2C,0x1073,0xC010,0x0000,0x0020,0x0003,
X	0xD000,0x0000,0x0020,0x0003,0xF620,0x0000,0x0020,0x0003,
X	0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF
END_OF_showpic.icon
if test 1933 -ne `wc -c <showpic.icon`; then
    echo shar: \"showpic.icon\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0