[comp.graphics] Raytrace to X Image converter

paul@torch.UUCP (Paul Andrews) (09/12/88)

Here's a somewhat primitive program to display one of Marks raytraced pic's
on an X display. There's no makefile, but then there's only one source file.

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
-----cut here-----cut here-----cut here-----cut here-----
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	readme
#	pictoximage.c
# This archive created: Mon Sep 12 11:09:47 1988
cat << \SHAR_EOF > readme
This is a first bash at getting one of Mark V's ray traced pic files up onto
an X screen. It reads the data and converts it into an 8 bit ZPixmap which
it then displays on the screen. It also creates a palette for this. It
doesn't:

1) Save this pixmap anywhere for later use.

2) Use the palette correctly.

3) Do any dithering.

4) Cope with anything other than an 8 bit pseudo colour display.

5) Cope with funny word/byte/bit orderings.

But it does work (on our Sun 3/60C). Hope you find it worth it.

Paul.
SHAR_EOF
cat << \SHAR_EOF > pictoximage.c
/*****************************************************************************
 *                                                                           *
 * Read a pic file and display it on an 8 bit X display.                     *
 *                                                                           *
 * Paul Andrews, 1988.                                                       *
 *                                                                           *
 * Copy and do with what you will, but I accept no responsibility for that.  *
 *                                                                           *
 *****************************************************************************/

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>

int w,h;		/* Width and height of image */
unsigned char *data;	/* The image data itself */

/*
 * Read the pic file in on stdin, display it on an X screen. We take one
 * argument, this will be used as the value for h and will override that
 * stored in the pic file. This allows you to display a partially completed
 * image if you get impatient (like me).
 */

main (argc, argv)
int argc;
char *argv[];

{
    int x,y;
    unsigned char r,g,b;
    Display *screen;
    Window window;
    XEvent event;
    XImage *image;
    Colormap colours;
    XColor colval;

    scanf("%d %d",&w,&h);

    if (argc == 2)
        sscanf (argv[1], "%d", &h);

    data = (unsigned char*) malloc(w*h);

    r = getchar();	/* Scrap the newline */

/*
 * Convert RGB triplets into a packed byte, R=3 bits, G=3 bits, B=2 bits.
 * This is ZPixmap format.
 */

    for (y=0; y<h; y++)
    {
        for (x=0; x<w; x++)
        {
            r = getchar();
            g = getchar();
            b = getchar();
            *(data+y*w+x) = (r & 0xe0) | (g >> 3 & 0x1c) | (b >> 6 & 0x3);
        }
    }

/* Now loads of X stuff. */

    screen = XOpenDisplay (NULL);
    window = XCreateSimpleWindow (screen, DefaultRootWindow(screen), 0, 0, w, h,
                         1, 0, 0);

/* Create a 256 colour palette */

    colours = XCreateColormap (screen, window, DefaultVisual(screen, DefaultScreen(screen)), AllocAll);

    colval.flags = DoRed | DoGreen | DoBlue;

    for (x=0; x<256; x++)
    {
        colval.pixel = x;
        colval.red = (x & 0xe0) << 8;
        colval.green = (x & 0x1c) << 11;
        colval.blue = (x & 3) << 14;
        XStoreColor (screen, colours, &colval);
    }

    XMapWindow (screen, window);

    XSetWindowColormap (screen, window, colours);

/* This is wrong. We shouldn't have to install the colour map. The window
   manager should do it. So whats going wrong? */

    XInstallColormap (screen, colours);

    XSelectInput (screen, window, ExposureMask);

    image = XCreateImage (screen, DefaultVisual(screen, DefaultScreen(screen)),
                          8, ZPixmap, 0, data, w, h, 8, 0);

    while (1)
    {
        XNextEvent (screen, &event);
        if (event.type == Expose)
            XPutImage (screen, window, DefaultGC (screen, DefaultScreen(screen)), image, 0, 0, 0, 0,
                       w, h);
    }
}
SHAR_EOF
#	End of shell archive
exit 0