ingwa@teorix.liu.se (Inge Wallin) (10/05/88)
Unfortunately, a bug crept into showpic. In the Floyd-Steinberg function floydfunc(), height and width were switched in the loop control. This didn't matter as long as one only used the program to view quadratic images, but would have resulted in very strange behaviours, and maybe even a core dump, if you had tried to look at rectangular ones. While I was at it, I made the program some 40% faster by skipping the calls to pr_put. I also fixed some grammar errors in the README and manual. Unfortunately the diffs were bigger than the entire posting of version 1.0, so I decided to send it all out again. ---------------------------clip here---------------------------- #! /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@teorix on Wed Oct 5 00:05:56 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\" \(2002 characters\) sed "s/^X//" >README <<'END_OF_README' X******************************************************************* X showpic 1.1 -- 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 file 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 mainly 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 is 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 XDifferences between 1.1 and 1.0: X* A bug fixed. (switch of width and height in floydfunc()) X* Faster program. Use own bit fiddling instead of pr_put. X* Possibility of looking at files which are not finished. This X was made while waiting for a major ray tracing to finish. X* Some grammar errors in this file and the manual were corrected. X (Very possibly some others have been introduced.) X XAs before, please send any enhancements, bug reports and fixes to us. X XLinkoping 4 Oct 1988 X X enjoy! /Inge & Jonas END_OF_README if test 2002 -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\" \(1741 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 4, 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.PP XThe program look for \fIEOF\fR, so it is possible to look at images which Xare not finished. X.SH OPTIONS X.IP \fB\-u\fR XShow program usage and exit. X.IP \fB\-f\fR XUse the Floyd\-Steinberg algorithm 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 \fIfilename\fR 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 \fBzcat\fR(1) to uncompress them. X.SH AUTHORS 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 1741 -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\" \(7915 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.1" 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 X/* typedef unsigned short u_short; */ /* already exists!!!??! */ X Xextern char *malloc(); X XFrame frame; XCanvas picture_canvas; XPixrect *picture_pr; X Xu_short *picture; X X Xtypedef struct dither { X int size; X int shift; X int *table; X} Dither; X X Xint 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 Xint 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 Xint 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}; Xint numdithers = sizeof(dithers) / sizeof(Dither); X X Xint redtab[256]; /* lookup tables for gray scale conversion */ Xint greentab[256]; Xint bluetab[256]; X Xchar *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 */ Xshort 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 CANVAS_AUTO_SHRINK, FALSE, X CANVAS_AUTO_EXPAND, FALSE, 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 y, x; X int red, green, blue; X int gray; X int *dithermat; X int dithersize; X int dithershifts; X u_short mask; X int offset; X X dithermat = dithers[dithernum].table; X dithersize = dithers[dithernum].size; X dithershifts = 8 + dithers[dithernum].shift; X X offset = 0; X for (y = 0; y < height; y++) { X mask = 0x8000; X for (x = 0; x < width; x++) { X red = getc(infile); X if (red == EOF) { X x = width; X y = height; X } else { X green = getc(infile); X blue = getc(infile); X gray = (redtab[red] + greentab[green] + bluetab[blue]) >> X dithershifts; X if ( gray < *(dithermat + (y % dithersize) * dithersize + X (x % dithersize)) ) { X *(picture + offset) |= mask; X } X X if ((mask >>= 1) == 0) { X mask = 0x8000; X offset++; X } X } X } X X if (mask != 0x8000) { X mask = 0x8000; X offset++; X } X } X} X X X Xvoid floydfunc(infile, width, height) XFILE *infile; Xint width; Xint height; X{ X int y, x; X int red, green, blue; X int gray; X int err; X char *buffer1; X char *buffer2; X char *temp; X u_short mask; X int offset; 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[y,x] */ X /* A[y, x+1] += err*7/16 */ X /* A[y+1, x-1] += err*3/16 */ X /* A[y+1, x ] += err*5/16 */ X /* A[y+1, x+1] += err*1/16 */ X for (y = 0; y < 256; y++) { X alphatab[y] = ((y - 128) * 7) / 16; X betatab[y] = ((y - 128) * 3) / 16; X gammatab[y] = ((y - 128) * 5) / 16; X deltatab[y] = ((y - 128) * 1) / 16; X } X X offset = 0; X for (y = 0; y < height; y++) { X err = 0; X for (x = 0; x < width + 2; x++) X *(buffer2 + x) = 0; X X mask = 0x8000; X for (x = 0; x < width; x++) { X red = getc(infile); X if (red == EOF) { X x = width; X y = height; X } else { X green = getc(infile); X blue = getc(infile); X gray = ((redtab[red] + greentab[green] + bluetab[blue]) >> 8) + X *(buffer1 + x + 1); X X if (gray < 128) { X *(picture + offset) |= mask; X err = gray; X } else { X err = gray - 256; X } X X if ((mask >>= 1) == 0) { X mask = 0x8000; X offset++; X } X X *(buffer1 + x + 2) += alphatab[err + 128]; X *(buffer2 + x ) += betatab[err + 128]; X *(buffer2 + x + 1) += gammatab[err + 128]; X *(buffer2 + x + 2) += deltatab[err + 128]; X } X } X temp = buffer1; X buffer1 = buffer2; X buffer2 = temp; X X if (mask != 0x8000) { X mask = 0x8000; X offset++; X } 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 picture = (u_short *) malloc(height * (width / 16 + 1) * sizeof(u_short)); X if (picture == NULL) X error("Couldn't allocate buffer for the picture"); 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 create_windows(infilename, width, height); X picture_pr = mem_point(width, height, 1, picture); X pw_write(canvas_pixwin(picture_canvas), 0, 0, width, height, X PIX_SRC, picture_pr, 0, 0); X X window_main_loop(frame); X exit(0); X} X X X END_OF_showpic.c if test 7915 -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 -- Inge Wallin | Thus spake the master programmer: | | "After three days without programming, | ingwa@majestix.liu.se | life becomes meaningless." | | Geoffrey James: The Tao of Programming. |