v01i019: Color Splines: Part 01/01
Charles Mcgrew
mcgrew at dartagnan.rutgers.edu
Sun May 28 07:17:17 AEST 1989
Submitted-by: Jef Poskanzer <jef at helios.ee.lbl.gov>
Posting-number: Volume 1, Issue 19
Archive-name: colorsplines
A cute hack indeed! Note that this posting is not in 'shar'
format, since its only the one file. Save it as spf3.c. Runs on sun3's
and sun4's - but only on color machines.
Charles
/*
** spf3.c - spline fun #3
**
** Compile: cc -O spf3.c -lpixrect -o spf3
**
** Run:
** spf3 spline fun
** spf3 -b spline fun with backwards colormap cycling
** spf3 -f spline fun with forwards colormap cycling
**
** Copyright (C) 1989 by Jef Poskanzer.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation. This software is provided "as is" without express or
** implied warranty.
**
** Comments to:
** jef at helios.ee.lbl.gov
** {ucbvax, lll-crg, sun!pacbell, apple, hplabs}!well!pokey
**
*/
#define POINTS 5
#define MAXDELTA 3
#define MAXCOLORDELTA 3
#include <stdio.h>
#include <sys/file.h>
#include <signal.h>
#include <sys/types.h>
#include <pixrect/pixrect_hs.h>
static unsigned char oldred[256], oldgreen[256], oldblue[256];
static int oldplanes;
static Pixrect *disp_pr;
main( argc, argv )
int argc;
char *argv[];
{
int argn, forward, backward;
int width, height, i, t, color;
int x[POINTS], y[POINTS], dx[POINTS], dy[POINTS];
int px, py, nx, ny, zx, zy;
unsigned char red[256], green[256], blue[256];
int dred, dgreen, dblue;
unsigned char nred, ngreen, nblue, tred, tgreen, tblue;
#define MAXGROUPS 10
char groups[MAXGROUPS];
Pixrect *my_pr_open();
int terminate();
char *usage = "usage: %s [-f|-b]\n";
argn = 1;
forward = 0;
backward = 0;
if ( argn < argc )
{
if ( strcmp( argv[argn], "-f" ) == 0 )
forward = 1;
else if ( strcmp( argv[argn], "-b" ) == 0 )
backward = 1;
else
{
fprintf( stderr, usage, argv[0] );
exit( 1 );
}
argn++;
}
if ( argn != argc )
{
fprintf( stderr, usage, argv[0] );
exit( 1 );
}
if ( (disp_pr = my_pr_open( "/dev/cgfive0" )) == (Pixrect *) 0 )
if ( (disp_pr = my_pr_open( "/dev/cgthree0" )) == (Pixrect *) 0 )
if ( (disp_pr = my_pr_open( "/dev/gpone0a" )) == (Pixrect *) 0 )
if ( (disp_pr = my_pr_open( "/dev/cgtwo0" )) == (Pixrect *) 0 )
if ( (disp_pr = my_pr_open( "/dev/cgfour0" )) == (Pixrect *) 0 )
if ( (disp_pr = my_pr_open( "/dev/cgone0" )) == (Pixrect *) 0 )
if ( (disp_pr = my_pr_open( "/dev/fb" )) == (Pixrect *) 0 )
{
fprintf( stderr, "%s: error opening display\n", argv[0] );
exit( 1 );
}
/* Save old state. */
pr_getcolormap( disp_pr, 0, 256, oldred, oldblue, oldgreen );
oldplanes = pr_get_plane_group( disp_pr );
signal( SIGHUP, terminate );
signal( SIGINT, terminate );
signal( SIGTERM, terminate );
width = disp_pr->pr_size.x;
height = disp_pr->pr_size.y;
srandom( (int) time( 0 ) );
(void) pr_available_plane_groups( disp_pr, MAXGROUPS, groups );
if ( ! groups[PIXPG_8BIT_COLOR] )
{
fprintf( stderr, "%s: display must implement 8-bit color\n", argv[0] );
exit( 1 );
}
pr_set_plane_group( disp_pr, PIXPG_8BIT_COLOR );
nred = ngreen = nblue = 0;
red[0] = green[0] = blue[0] = 255;
for ( color = 1; color < 256; color++ )
red[color] = green[color] = blue[color] = 0;
pr_putcolormap( disp_pr, 0, 256, red, green, blue );
pr_rop( disp_pr, 0, 0, width, height, PIX_SRC | PIX_COLOR(1), 0, 0, 0 );
signit( disp_pr );
dred = random() % ( MAXCOLORDELTA * 2 ) - MAXCOLORDELTA;
if ( dred <= 0 ) dred--;
dgreen = random() % ( MAXCOLORDELTA * 2 ) - MAXCOLORDELTA;
if ( dgreen <= 0 ) dgreen--;
dblue = random() % ( MAXCOLORDELTA * 2 ) - MAXCOLORDELTA;
if ( dblue <= 0 ) dblue--;
for ( i = 0; i < POINTS; i++ )
{
x[i] = random() % width;
y[i] = random() % height;
dx[i] = random() % ( MAXDELTA * 2 ) - MAXDELTA;
if ( dx[i] <= 0 ) dx[i]--;
dy[i] = random() % ( MAXDELTA * 2 ) - MAXDELTA;
if ( dy[i] <= 0 ) dy[i]--;
}
/* Main loop. */
color = 1;
for ( ; ; )
{
/* Choose new color. */
if ( ++color == 256 ) color = 2;
for ( ; ; )
{
t = (int) nred + dred;
if ( t >= 0 && t < 256 ) break;
dred = random() % ( MAXCOLORDELTA * 2 ) - MAXCOLORDELTA;
if ( dred <= 0 ) dred--;
}
red[color] = nred = t;
for ( ; ; )
{
t = (int) ngreen + dgreen;
if ( t >= 0 && t < 256 ) break;
dgreen = random() % ( MAXCOLORDELTA * 2 ) - MAXCOLORDELTA;
if ( dgreen <= 0 ) dgreen--;
}
green[color] = ngreen = t;
for ( ; ; )
{
t = (int) nblue + dblue;
if ( t >= 0 && t < 256 ) break;
dblue = random() % ( MAXCOLORDELTA * 2 ) - MAXCOLORDELTA;
if ( dblue <= 0 ) dblue--;
}
blue[color] = nblue = t;
pr_putcolormap( disp_pr, 0, 256, red, green, blue );
/* Move the points. */
for ( i = 0; i < POINTS; i++ )
{
for ( ; ; )
{
t = x[i] + dx[i];
if ( t >= 0 && t < width ) break;
dx[i] = random() % ( MAXDELTA * 2 ) - MAXDELTA;
if ( dx[i] <= 0 ) dx[i]--;
}
x[i] = t;
for ( ; ; )
{
t = y[i] + dy[i];
if ( t >= 0 && t < height ) break;
dy[i] = random() % ( MAXDELTA * 2 ) - MAXDELTA;
if ( dy[i] <= 0 ) dy[i]--;
}
y[i] = t;
}
/* Draw the figure. */
px = zx = ( x[0] + x[POINTS-1] ) / 2;
py = zy = ( y[0] + y[POINTS-1] ) / 2;
for ( i = 0; i < POINTS-1; i++ )
{
nx = ( x[i+1] + x[i] ) / 2;
ny = ( y[i+1] + y[i] ) / 2;
pr_spline3(
disp_pr, px, py, x[i], y[i], nx, ny,
PIX_SRC | PIX_COLOR(color), 0 );
px = nx;
py = ny;
}
pr_spline3(
disp_pr, px, py, x[POINTS-1], y[POINTS-1], zx, zy,
PIX_SRC | PIX_COLOR(color), 0 );
/* Cycle colormap. */
if ( forward )
{
if ( color % 2 == 0 )
{
/* Cycle colors forward. */
tred = red[255];
tgreen = green[255];
tblue = blue[255];
for ( i = 254; i >= 2; i-- )
{
red[i+1] = red[i];
green[i+1] = green[i];
blue[i+1] = blue[i];
}
red[2] = tred;
green[2] = tgreen;
blue[2] = tblue;
}
}
else if ( backward )
{
/* Cycle colors backward. */
tred = red[2];
tgreen = green[2];
tblue = blue[2];
for ( i = 3; i <= 255; i++ )
{
red[i-1] = red[i];
green[i-1] = green[i];
blue[i-1] = blue[i];
}
red[255] = tred;
green[255] = tgreen;
blue[255] = tblue;
red[color] = nred;
green[color] = ngreen;
blue[color] = nblue;
}
}
}
Pixrect *
my_pr_open( fb )
char *fb;
{
int fd;
/* Test with open first, to avoid stupid error messages from pr_open(). */
if ( (fd = open(fb, O_RDWR)) == -1 )
return (Pixrect *) 0;
close( fd );
return pr_open( fb );
}
static short posk_image[] = {
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffe7,0xcfff,0xffe7,0xcfff,
0xffe7,0x9fff,0xffcf,0xbfff,0xffcf,0x3fff,0xffdf,0x507f,
0xff8e,0x7e3f,0xff6e,0x7e7f,0xffcf,0x7e3f,0xffcf,0x7c7f,
0xffcf,0x067f,0xffcf,0x0e7f,0xffce,0x7e7f,0xffcf,0x7c7f,
0xffce,0x2a7f,0xffcf,0x14ff,0xffcf,0xfcff,0xffcf,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xfffc,0x7fff,
0xfffe,0x3fff,0xfffe,0x3fff,0xfffe,0x3fff,0xfffe,0x3fff,
0xffff,0x3fff,0xfffe,0x107f,0xffa0,0x007f,0xfc1e,0x3fff,
0xffff,0x3fff,0xfffe,0x1fff,0xffff,0x3fff,0xfffe,0x3fff,
0xfffe,0x3fff,0xffff,0x3fff,0xfffe,0x2bff,0xffe8,0x01ff,
0xff05,0xd8ff,0xff7f,0xffff,0xffff,0xffff,0xff83,0xfcff,
0xfe67,0xe0ff,0xfe47,0x9dff,0xfe13,0xf9ff,0xfe7b,0xb3ff,
0xfe43,0x87ff,0xfe27,0xc7ff,0xfe65,0xc3ff,0xfc00,0x707f,
0xfe3e,0x7c3f,0xffff,0x3fff,0xffff,0x2fff,0xfff8,0x1fff,
0xfffe,0x2fff,0xffe0,0x01ff,0xff82,0xa8ff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xefff,0xffff,0xe7ff,0xffc7,0xe7ff,
0xfff3,0xe7ff,0xffff,0xe7ff,0xffdf,0x667f,0xff1f,0x263f,
0xffdf,0x27ff,0xffff,0x69ff,0xfffd,0xc1ff,0xfffb,0xe1ff,
0xfffb,0xf1ff,0xfff7,0xf3ff,0xfff7,0xe7ff,0xffe7,0xc7ff,
0xffef,0xcfff,0xffcf,0x9fff,0xff8f,0x3fff,0xff9e,0x7fff,
0xffdc,0xffff,0xfffb,0xffff,0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff };
mpr_static( posk, 32, 92, 1, posk_image );
signit( pr )
Pixrect *pr;
{
#ifdef sun386
pr_flip( &posk );
#endif sun386
pr_rop(
pr, pr->pr_size.x - posk.pr_size.x, pr->pr_size.y - posk.pr_size.y,
posk.pr_size.x, posk.pr_size.y,
PIX_SRC | PIX_COLOR(1), &posk, 0, 0 );
}
int
terminate( sig, code, scp )
int sig, code;
struct sigcontext *scp;
{
pr_putcolormap( disp_pr, 0, 256, oldred, oldgreen, oldblue );
pr_set_plane_group( disp_pr, oldplanes );
pr_rop(
disp_pr, 0, 0, disp_pr->pr_size.x, disp_pr->pr_size.y,
PIX_CLR, 0, 0, 0 );
exit( 0 );
}
#define abs(x) ((x) < 0 ? -(x) : (x))
#define SPLINE_THRESH 3
pr_spline3( pr, x0, y0, x1, y1, x2, y2, op, value )
Pixrect *pr;
int x0, y0, x1, y1, x2, y2, op, value;
{
register int xa, ya, xb, yb, xc, yc, xp, yp;
xa = ( x0 + x1 ) / 2;
ya = ( y0 + y1 ) / 2;
xc = ( x1 + x2 ) / 2;
yc = ( y1 + y2 ) / 2;
xb = ( xa + xc ) / 2;
yb = ( ya + yc ) / 2;
xp = ( x0 + xb ) / 2;
yp = ( y0 + yb ) / 2;
if ( abs( xa - xp ) + abs( ya - yp ) > SPLINE_THRESH )
pr_spline3( pr, x0, y0, xa, ya, xb, yb, op, value );
else
pr_vector( pr, x0, y0, xb, yb, op, value );
xp = ( x2 + xb ) / 2;
yp = ( y2 + yb ) / 2;
if ( abs( xc - xp ) + abs( yc - yp ) > SPLINE_THRESH )
pr_spline3( pr, xb, yb, xc, yc, x2, y2, op, value );
else
pr_vector( pr, xb, yb, x2, y2, op, value );
}
More information about the Comp.sources.sun
mailing list