home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume22
/
popi
/
part03
< prev
next >
Wrap
Text File
|
1991-08-22
|
61KB
|
2,319 lines
Newsgroups: comp.sources.misc
From: Rich Burridge <richb@Aus.Sun.COM>
Subject: v22i042: popi - The Digital Darkroom, Part03/09
Message-ID: <1991Aug22.165620.17321@sparky.IMD.Sterling.COM>
X-Md4-Signature: aee1769fdbd1d4b66e51f73eedbf4110
Date: Thu, 22 Aug 1991 16:56:20 GMT
Approved: kent@sparky.imd.sterling.com
Submitted-by: Rich Burridge <richb@Aus.Sun.COM>
Posting-number: Volume 22, Issue 42
Archive-name: popi/part03
Environment: Xlib, Xview, SunView
Supersedes: popi: Volume 9, Issue 47-55
#! /bin/sh
# 1. Remove everything above the #! /bin/sh line
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh to create the files:
# libpbm.c
# libpbm.h
# run.c
# special.c
# popi.icon
# This archive created: Wed Aug 21 10:35:53 EST 1991
#
#
export PATH; PATH=/bin:$PATH
#
if [ -f libpbm.c ]
then
echo shar: will not over-write existing file libpbm.c
else
echo shar: extracting 'libpbm.c', 15728 characters
cat > libpbm.c <<'Funky_Stuff'
/* @(#)libpbm.c 1.4 91/01/17
*
* PBM/PGM/PPM routines used by the popi program.
*
* Popi was originally written by Gerard J. Holzmann - AT&T Bell Labs.
* This version is based on the code in his Prentice Hall book,
* "Beyond Photography - the digital darkroom," ISBN 0-13-074410-7,
* which is copyright (c) 1988 by Bell Telephone Laboratories, Inc.
*
* Permission is given to distribute these extensions, as long as these
* introductory messages are not removed, and no monies are exchanged.
*
* No responsibility is taken for any errors or inaccuracies inherent
* either to the comments or the code of this program, but if reported
* (see README file) then an attempt will be made to fix them.
*/
/* Based on routines from the PBMPLUS utility libraries.
*
* 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.
*/
#include <stdio.h>
#include "popi.h"
#include "libpbm.h"
static bit pbm_getbit P(( FILE * )) ;
static char pbm_getc P(( FILE * )) ;
static unsigned char pbm_getrawbyte P(( FILE * )) ;
static int pbm_getint P(( FILE * )) ;
static int pbm_readmagicnumber P(( FILE * )) ;
static void pbm_readpbminitrest P(( FILE *, int *, int *)) ;
static void pgm_readpgminitrest P(( FILE *, int *, int *, gray * )) ;
static void ppm_readppminitrest P(( FILE *, int *, int *, pixval * )) ;
static void pm_error P(( char *, char *, char *, char *, char *, char * )) ;
static void pm_message P(( char *, char *, char *, char *, char *, char * )) ;
static void pm_perror P(( char * )) ;
static void pbm_readpbmrow P(( FILE *, bit *, int, int)) ;
static void pgm_writepgmrowraw P(( FILE *, gray *, int, gray)) ;
static void pgm_writepgmrowplain P(( FILE *, gray *, int, gray)) ;
static void ppm_writeppmrowraw P(( FILE *, pixel *, int, pixval)) ;
static void ppm_writeppmrowplain P(( FILE *, pixel *, int, pixval)) ;
static char *pm_progname ;
static bit *bitrow ;
static gray *grayrow ;
int pm_iserror = FALSE ;
static bit
pbm_getbit(file)
FILE *file ;
{
register char ch ;
do
{
ch = pbm_getc(file) ;
}
while (ch == ' ' || ch == '\t' || ch == '\n') ;
if (ch != '0' && ch != '1')
pm_error("junk in file where bits should be",
(char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0) ;
return((ch == '1') ? 1 : 0) ;
}
static char
pbm_getc(file)
FILE *file ;
{
register int ich ;
register char ch ;
ich = getc(file) ;
if (ich == EOF)
pm_error("premature EOF",
(char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0) ;
ch = (char) ich ;
if (ch == '#')
{
do
{
ich = getc(file) ;
if (ich == EOF)
pm_error("premature EOF", (char *) 0, (char *) 0,
(char *) 0, (char *) 0, (char *) 0) ;
ch = (char) ich ;
}
while ( ch != '\n' );
}
return(ch) ;
}
static unsigned char
pbm_getrawbyte(file)
FILE *file ;
{
register int iby ;
iby = getc(file) ;
if (iby == EOF)
pm_error("premature EOF",
(char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0) ;
return((unsigned char) iby) ;
}
static int
pbm_getint(file)
FILE *file ;
{
register char ch ;
register int i ;
do
{
ch = pbm_getc(file) ;
if (pm_iserror == TRUE) return(0) ;
}
while (ch == ' ' || ch == '\t' || ch == '\n') ;
if (ch < '0' || ch > '9')
{
pm_error("junk in file where an integer should be",
(char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0) ;
return(0) ;
}
i = 0 ;
do
{
i = i * 10 + ch - '0' ;
ch = pbm_getc(file) ;
if (pm_iserror == TRUE) return(0) ;
}
while (ch >= '0' && ch <= '9') ;
return(i) ;
}
static int
pbm_readmagicnumber(file)
FILE *file ;
{
int ich1, ich2 ;
ich1 = getc(file) ;
if (ich1 == EOF)
pm_error("premature EOF reading magic number",
(char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0) ;
ich2 = getc(file) ;
if (ich2 == EOF)
pm_error("premature EOF reading magic number",
(char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0) ;
return(ich1 * 256 + ich2) ;
}
static void
pbm_readpbminitrest(file, colsP, rowsP)
FILE *file ;
int *colsP, *rowsP ;
{
*colsP = pbm_getint(file) ; /* Read size. */
*rowsP = pbm_getint(file) ;
}
static void
pbm_readpbmrow(file, bitrow, cols, format)
FILE *file ;
bit *bitrow ;
int cols, format ;
{
register int col, bitshift ;
register unsigned char item ;
register bit *bP ;
switch (format)
{
case PBM_FORMAT : for (col = 0, bP = bitrow; col < cols; col++, bP++)
*bP = pbm_getbit(file) ;
break ;
case RPBM_FORMAT : bitshift = -1 ;
for (col = 0, bP = bitrow; col < cols; col++, bP++)
{
if (bitshift == -1)
{
item = pbm_getrawbyte(file) ;
bitshift = 7 ;
}
*bP = (item >> bitshift) & 1 ;
bitshift-- ;
}
break ;
default : pm_error("can't happen", (char *) 0, (char *) 0,
(char *) 0, (char *) 0, (char *) 0) ;
}
}
static void
pgm_readpgminitrest(file, colsP, rowsP, maxvalP)
FILE *file ;
int *colsP, *rowsP ;
gray *maxvalP ;
{
*colsP = pbm_getint(file) ; /* Read size. */
*rowsP = pbm_getint(file) ;
*maxvalP = pbm_getint(file) ; /* Read maxval. */
if (*maxvalP > PGM_MAXMAXVAL)
pm_error("maxval too large - %d > %d\n",
(char *) *maxvalP, (char *) PGM_MAXMAXVAL,
(char *) 0, (char *) 0, (char *) 0) ;
}
/*ARGSUSED*/
void
pgm_readpgmrow(file, grayrow, cols, maxval, format)
FILE *file ;
gray *grayrow ;
int cols, format ;
gray maxval ;
{
register int col ;
register gray *gP ;
register bit *bP ;
switch (format)
{
case PGM_FORMAT : for (col = 0, gP = grayrow; col < cols; col++, gP++)
{
*gP = pbm_getint(file) ;
if (pm_iserror == TRUE) return ;
}
break ;
case RPGM_FORMAT : for (col = 0, gP = grayrow; col < cols; col++, gP++)
{
*gP = pbm_getrawbyte(file) ;
if (pm_iserror == TRUE) return ;
}
break ;
case PBM_FORMAT :
case RPBM_FORMAT : pbm_readpbmrow(file, bitrow, cols, format) ;
gP = grayrow ;
bP = bitrow ;
for (col = 0; col < cols; col++, gP++, bP++)
*gP = (*bP == PBM_WHITE) ? maxval : 0 ;
break ;
default : pm_error("can't happen", (char *) 0, (char *) 0,
(char *) 0, (char *) 0, (char *) 0) ;
}
}
void
pgm_writepgminit(file, cols, rows, maxval)
FILE *file ;
int cols, rows ;
gray maxval ;
{
if (maxval <= 255)
FPRINTF(file, "%c%c\n%d %d\n%d\n", PGM_MAGIC1, RPGM_MAGIC2,
cols, rows, maxval) ;
else
FPRINTF(file, "%c%c\n%d %d\n%d\n", PGM_MAGIC1, PGM_MAGIC2,
cols, rows, maxval) ;
}
void
pgm_writepgmrow(file, grayrow, cols, maxval)
FILE *file ;
gray *grayrow ;
int cols ;
gray maxval ;
{
if (maxval <= 255) pgm_writepgmrowraw(file, grayrow, cols, maxval) ;
else pgm_writepgmrowplain(file, grayrow, cols, maxval) ;
}
/*ARGSUSED*/
static void
pgm_writepgmrowraw(file, grayrow, cols, maxval)
FILE *file ;
gray *grayrow ;
int cols ;
gray maxval ;
{
register int col ;
register gray *gP ;
for (col = 0, gP = grayrow; col < cols; col++, gP++)
if (putc((char) *gP, file) == EOF) pm_perror((char *) 0) ;
}
/*ARGSUSED*/
static void
pgm_writepgmrowplain(file, grayrow, cols, maxval)
FILE *file ;
gray *grayrow ;
int cols ;
gray maxval ;
{
register int col, charcount ;
register gray *gP ;
charcount = 0 ;
for (col = 0, gP = grayrow; col < cols; col++, gP++)
{
if (charcount >= 70)
{
if (putc('\n', file) == EOF) pm_perror((char *) 0) ;
charcount = 0 ;
}
if (putus((unsigned int) *gP, file) == EOF) pm_perror((char *) 0) ;
if (putc(' ', file) == EOF) pm_perror((char *) 0) ;
charcount += 4 ;
}
if (putc('\n', file) == EOF) pm_perror((char *) 0) ;
}
char *
pm_allocrow(cols, size)
int cols ;
{
register char *itrow ;
itrow = (char *) malloc((unsigned int) (cols * size)) ;
if (itrow == (char *) 0)
pm_error("out of memory allocating a row",
(char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0) ;
return(itrow) ;
}
static void
pm_error(fmt, v1, v2, v3, v4, v5)
char *fmt, *v1, *v2, *v3, *v4, *v5 ;
{
pm_message(fmt, v1, v2, v3, v4, v5) ;
pm_iserror = TRUE ;
}
void
pm_freerow(itrow)
char *itrow ;
{
FREE(itrow) ;
}
static void
pm_message(fmt, v1, v2, v3, v4, v5)
char *fmt, *v1, *v2, *v3, *v4, *v5 ;
{
FPRINTF(stderr, "%s: ", pm_progname) ;
FPRINTF(stderr, fmt, v1, v2, v3, v4, v5) ;
FPUTC('\n', stderr) ;
}
static void
pm_perror(reason)
char *reason ;
{
extern char *sys_errlist[] ;
extern int errno ;
char *e ;
if (errno == 0) e = "end of file" ; /* Not particularly kosher. */
else e = sys_errlist[errno] ;
if (reason != 0 && reason[0] != '\0')
pm_error("%s - %s", reason, e, (char *) 0, (char *) 0, (char *) 0) ;
else
pm_error("%s", e, (char *) 0, (char *) 0, (char *) 0, (char *) 0) ;
}
void
ppm_readppminit(file, colsP, rowsP, maxvalP, formatP)
FILE *file ;
int *colsP, *rowsP, *formatP ;
pixval *maxvalP ;
{
*formatP = pbm_readmagicnumber(file) ; /* Check magic number. */
switch (*formatP)
{
case PPM_FORMAT :
case RPPM_FORMAT : ppm_readppminitrest(file, colsP, rowsP, maxvalP) ;
break ;
case PGM_FORMAT :
case RPGM_FORMAT : pgm_readpgminitrest(file, colsP, rowsP, maxvalP) ;
grayrow = pgm_allocrow(*colsP) ;
break ;
case PBM_FORMAT :
case RPBM_FORMAT : pbm_readpbminitrest(file, colsP, rowsP) ;
*maxvalP = PPM_PBMMAXVAL ;
bitrow = pbm_allocrow(*colsP) ;
break ;
default : *formatP = OLD_POPI_FORMAT ; /* Let's hope it is. */
rewind(file) ;
}
}
static void
ppm_readppminitrest(file, colsP, rowsP, maxvalP)
FILE *file ;
int *colsP, *rowsP ;
pixval *maxvalP ;
{
*colsP = pbm_getint(file) ; /* Read size. */
*rowsP = pbm_getint(file) ;
*maxvalP = pbm_getint(file) ; /* Read maxval. */
if (*maxvalP > PPM_MAXMAXVAL)
pm_error("maxval too large - %d > %d",
(char *) *maxvalP, (char *) PPM_MAXMAXVAL,
(char *) 0, (char *) 0, (char *) 0) ;
}
void
ppm_readppmrow(file, pixelrow, cols, maxval, format)
FILE *file ;
pixel *pixelrow ;
int cols, format ;
pixval maxval ;
{
register int col ;
register pixel *pP ;
register pixval r, g, b ;
register gray *gP ;
switch (format)
{
case PPM_FORMAT : for (col = 0, pP = pixelrow; col < cols; col++, pP++)
{
r = pbm_getint(file) ;
g = pbm_getint(file) ;
b = pbm_getint(file) ;
if (pm_iserror == TRUE) return ;
PPM_ASSIGN(*pP, r, g, b) ;
}
break ;
case RPPM_FORMAT : for (col = 0, pP = pixelrow; col < cols; col++, pP++)
{
r = pbm_getrawbyte(file) ;
g = pbm_getrawbyte(file) ;
b = pbm_getrawbyte(file) ;
if (pm_iserror == TRUE) return ;
PPM_ASSIGN(*pP, r, g, b) ;
}
break ;
case PGM_FORMAT :
case RPGM_FORMAT : pgm_readpgmrow(file, grayrow, cols, maxval, format) ;
gP = grayrow ;
pP = pixelrow ;
for (col = 0; col < cols; col++, gP++, pP++)
{
r = *gP ;
if (pm_iserror == TRUE) return ;
PPM_ASSIGN(*pP, r, r, r) ;
}
break ;
default : pm_error("can't happen", (char *) 0, (char *) 0,
(char *) 0, (char *) 0, (char *) 0) ;
}
}
void
ppm_writeppminit(file, cols, rows, maxval)
FILE *file ;
int cols, rows ;
pixval maxval ;
{
if (maxval <= 255)
FPRINTF(file, "%c%c\n%d %d\n%d\n", PPM_MAGIC1, RPPM_MAGIC2,
cols, rows, maxval) ;
else
FPRINTF(file, "%c%c\n%d %d\n%d\n", PPM_MAGIC1, PPM_MAGIC2,
cols, rows, maxval) ;
}
void
ppm_writeppmrow(file, pixelrow, cols, maxval)
FILE *file ;
pixel *pixelrow ;
int cols ;
pixval maxval ;
{
if (maxval <= 255) ppm_writeppmrowraw(file, pixelrow, cols, maxval) ;
else ppm_writeppmrowplain(file, pixelrow, cols, maxval) ;
}
/*ARGSUSED*/
static void
ppm_writeppmrowraw(file, pixelrow, cols, maxval)
FILE *file ;
pixel *pixelrow ;
int cols ;
pixval maxval ;
{
register int col ;
register pixel *pP ;
register pixval val ;
for (col = 0, pP = pixelrow; col < cols; col++, pP++)
{
val = PPM_GETR(*pP) ;
if (putc((char) val, file) == EOF) pm_perror((char *) 0) ;
val = PPM_GETG(*pP) ;
if (putc((char) val, file) == EOF) pm_perror((char *) 0) ;
val = PPM_GETB(*pP) ;
if (putc((char) val, file) == EOF) pm_perror((char *) 0) ;
}
}
/*ARGSUSED*/
static void
ppm_writeppmrowplain(file, pixelrow, cols, maxval)
FILE *file ;
pixel *pixelrow ;
int cols;
pixval maxval ;
{
register int col, charcount ;
register pixel *pP ;
register pixval val ;
charcount = 0 ;
for (col = 0, pP = pixelrow; col < cols; col++, pP++)
{
if (charcount >= 70)
{
if (putc('\n', file) == EOF) pm_perror((char *) 0) ;
charcount = 0 ;
}
val = PPM_GETR(*pP) ;
if (putus(val, file) == EOF) pm_perror((char *) 0) ;
if (putc(' ', file) == EOF) pm_perror((char *) 0) ;
val = PPM_GETG(*pP) ;
if (putus(val, file) == EOF) pm_perror((char *) 0) ;
if (putc(' ', file) == EOF) pm_perror((char *) 0) ;
val = PPM_GETB(*pP) ;
if (putus(val, file) == EOF) pm_perror((char *) 0) ;
if (putc(' ', file) == EOF) pm_perror((char *) 0) ;
if (putc(' ', file) == EOF) pm_perror((char *) 0) ;
charcount += 13 ;
}
if (putc('\n', file) == EOF) pm_perror((char *) 0) ;
}
static int
putus(n, file)
unsigned int n ;
FILE *file ;
{
if (n >= 10)
if (putus(n / 10, file) == EOF) return(EOF) ;
return(putc((char) (n % 10 + '0'), file)) ;
}
Funky_Stuff
len=`wc -c < libpbm.c`
if [ $len != 15728 ] ; then
echo error: libpbm.c was $len bytes long, should have been 15728
fi
fi # end of overwriting check
if [ -f libpbm.h ]
then
echo shar: will not over-write existing file libpbm.h
else
echo shar: extracting 'libpbm.h', 3227 characters
cat > libpbm.h <<'Funky_Stuff'
/* @(#)libpbm.h 1.4 91/01/17
*
* PBM/PGM/PPM definitions used by the popi program.
*
* Popi was originally written by Gerard J. Holzmann - AT&T Bell Labs.
* This version is based on the code in his Prentice Hall book,
* "Beyond Photography - the digital darkroom," ISBN 0-13-074410-7,
* which is copyright (c) 1988 by Bell Telephone Laboratories, Inc.
*
* Permission is given to distribute these extensions, as long as these
* introductory messages are not removed, and no monies are exchanged.
*
* No responsibility is taken for any errors or inaccuracies inherent
* either to the comments or the code of this program, but if reported
* (see README file) then an attempt will be made to fix them.
*/
/* Based on definitions from the PBMPLUS utility libraries.
*
* 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.
*/
typedef unsigned char bit ;
typedef unsigned char gray ;
typedef gray pixval ;
typedef struct {
pixval r, g, b ;
} pixel ;
#define OLD_POPI_FORMAT -1
#define PBM_WHITE 0
#define PBM_BLACK 1
#define PBM_MAGIC1 'P'
#define PBM_MAGIC2 '1'
#define RPBM_MAGIC2 '4'
#define PBM_FORMAT (PBM_MAGIC1 * 256 + PBM_MAGIC2)
#define RPBM_FORMAT (PBM_MAGIC1 * 256 + RPBM_MAGIC2)
#define PPM_PBMMAXVAL 1
#define PGM_MAGIC1 'P'
#define PGM_MAGIC2 '2'
#define RPGM_MAGIC2 '5'
#define PGM_FORMAT (PGM_MAGIC1 * 256 + PGM_MAGIC2)
#define RPGM_FORMAT (PGM_MAGIC1 * 256 + RPGM_MAGIC2)
#define PGM_MAXMAXVAL 255
#define PPM_MAGIC1 'P'
#define PPM_MAGIC2 '3'
#define RPPM_MAGIC2 '6'
#define PPM_FORMAT (PPM_MAGIC1 * 256 + PPM_MAGIC2)
#define RPPM_FORMAT (PPM_MAGIC1 * 256 + RPPM_MAGIC2)
#define PPM_MAXMAXVAL PGM_MAXMAXVAL
#define pbm_allocrow(cols) ((bit *) pm_allocrow(cols, sizeof(bit)))
#define pgm_allocrow(cols) ((gray *) pm_allocrow(cols, sizeof(gray)))
#define ppm_allocrow(cols) ((pixel *) pm_allocrow(cols, sizeof(pixel)))
#define pgm_freerow(grayrow) pm_freerow((char *) grayrow)
#define ppm_freerow(pixelrow) pm_freerow((char *) pixelrow)
#define PPM_GETR(p) ((p).r)
#define PPM_GETG(p) ((p).g)
#define PPM_GETB(p) ((p).b)
#define PPM_ASSIGN(p, red, grn, blu) \
do { (p).r = (red) ; (p).g = (grn) ; (p).b = (blu) ; } while (0)
char *pm_allocrow P(( int, int )) ;
void pgm_readpgmrow P(( FILE *, gray *, int, gray, int )) ;
void pgm_writepgminit P(( FILE *, int, int, gray )) ;
void pgm_writepgmrow P(( FILE *, gray *, int, gray )) ;
void pm_freerow P(( char * )) ;
void ppm_readppminit P(( FILE *, int *, int *, pixval *, int * )) ;
void ppm_readppmrow P(( FILE *, pixel *, int, pixval, int )) ;
void ppm_writeppminit P(( FILE *, int, int, pixval )) ;
void ppm_writeppmrow P(( FILE *, pixel *, int, pixval )) ;
Funky_Stuff
len=`wc -c < libpbm.h`
if [ $len != 3227 ] ; then
echo error: libpbm.h was $len bytes long, should have been 3227
fi
fi # end of overwriting check
if [ -f run.c ]
then
echo shar: will not over-write existing file run.c
else
echo shar: extracting 'run.c', 14422 characters
cat > run.c <<'Funky_Stuff'
/* @(#)run.c 1.4 91/08/21
*
* Run time interpreter used by the popi program.
*
* Popi was originally written by Gerard J. Holzmann - AT&T Bell Labs.
* This version is based on the code in his Prentice Hall book,
* "Beyond Photography - the digital darkroom," ISBN 0-13-074410-7,
* which is copyright (c) 1988 by Bell Telephone Laboratories, Inc.
*
* Permission is given to distribute these extensions, as long as these
* introductory messages are not removed, and no monies are exchanged.
*
* No responsibility is taken for any errors or inaccuracies inherent
* either to the comments or the code of this program, but if reported
* (see README file) then an attempt will be made to fix them.
*/
#include <ctype.h>
#include "popi.h"
#if SEQPAR
#include <parallel/microtask.h>
#endif /* SEQPAR */
#define STACKSIZE 128
#define dop(OP) a = *--sp ; tp = sp-1 ; *tp = (*tp OP (stack_t) a)
/* Local function prototypes */
void prun P((void)) ;
void
SwapOldNew()
{
struct SRC *tmp ;
tmp = CurOld ;
CurOld = CurNew ;
CurNew = tmp ;
}
static void
prun()
{
long *ParseEnd ; /* After end of parse string */
int color ;
int x ;
int y ; /* Coordinates */
int nrange = 0 ; /* No. range errors */
ParseEnd = &parsed[prs] ;
#ifndef NDEBUG
if (Debug)
{
register long *CurrParse ; /* Pointer to current item in parse string */
FPRINTF(Debug, "Parse string\n") ;
for (CurrParse = parsed; CurrParse != ParseEnd; ++CurrParse)
FPRINTF(Debug, "'%c' (%ld)\n", (char) *CurrParse, *CurrParse) ;
FPRINTF(Debug, "---\n") ;
}
#endif /* NDEBUG */
/* Warning: Microsoft Quick C generates incorrect code for the following
* loop when optimisation is turned on.
*/
#ifndef SEQPAR
for (y = 0; y < Ysize; ++y)
#else /* ! SEQPAR */
for (y = m_myid; y < Ysize; y += m_numprocs)
#endif /* ! SEQPAR */
{
short *ap ; /* Precalculated polar angles */
short *rp ; /* Precalculated polar radius */
register pixel_t *pixp ; /* Default destination */
ap = &avals[y * Xsize] ;
rp = &rvals[y * Xsize] ;
for (color = 0; color < colors; ++color)
{
pixp = CurNew->pix[y][color] ;
DEBUG((Debug, "y = %d\n", y)) ;
for (x = 0; x < Xsize; ++x, ++pixp)
{
stack_t Stack[STACKSIZE] ; /* The stack */
register stack_t *sp ; /* Stack pointer (top of stack) */
register stack_t *tp ; /* Temp stack pointer */
stack_t a ;
stack_t b ;
int c ; /* Scratch */
register pixel_t *u ; /* Explicit destination */
register long *CurrParse ; /* Pointer to current item */
/* in parse string */
for (CurrParse = parsed, sp = Stack; CurrParse != ParseEnd;
++CurrParse)
{
switch ((int) *CurrParse)
{
case OP_VALUE : *sp++ = (stack_t) *++CurrParse ;
continue ;
case OP_AT : --sp ;
if (Truncate)
{
if (*sp > Zmax) *sp = Zmax ;
else if (*sp < 0) *sp = 0 ;
}
*pixp = (pixel_t) *sp ;
continue ;
case OP_PLUS : dop(+) ;
break ;
case OP_MINUS : dop(-) ;
break ;
case OP_MUL : dop(*) ;
break ;
case OP_DIV : a = *--sp ;
tp = sp-1 ;
if (a == 0) *tp = Zmax ;
else *tp = (*tp / (stack_t) a) ;
break ;
case OP_MOD : a = *--sp ;
tp = sp-1 ;
if (a == 0) *tp = 0 ;
else *tp = (*tp % (stack_t) a) ;
break ;
case OP_GT : dop(>) ;
break ;
case OP_LT : dop(<) ;
break ;
case OP_GE : dop(>=) ;
break ;
case OP_LE : dop(<=) ;
break ;
case OP_EQ : dop(==) ;
break ;
case OP_NE : dop(!=) ;
break ;
case OP_CAND : dop(&&) ;
break ;
case OP_COR : dop(||) ;
break ;
case OP_XOR : dop(^) ;
break ;
case OP_OR : dop(|) ;
break ;
case OP_AND : dop(&) ;
break ;
case OP_X : *sp++ = (stack_t) x ;
break ;
case OP_Y : *sp++ = (stack_t) y ;
break ;
case OP_UMIN : tp = sp-1 ;
*tp = -(*tp) ;
break ;
case OP_NOT : tp = sp-1 ;
*tp = !(*tp) ;
break ;
case OP_ASGN : a = *--sp ;
u = (pixel_t *) *--sp ;
if (Truncate)
{
if (a > Zmax) a = Zmax ;
else if (a < 0) a = 0 ;
}
*u = (pixel_t) a ;
break ;
case OP_CRVAL : a = *--sp ; /* y */
b = *--sp ; /* x */
tp = sp-1 ;
c = (int) *tp ;
if (RangeCheck &&
(a > Xsize - 1 || a < 0 ||
b > Ysize - 1 || b < 0))
{
if (nrange++ == 0)
FPRINTF(stderr,
"Range err at (%d,%d) => %s[%d, %d]\n",
x, y, Images[c].str, b, a) ;
}
if (a >= Ysize) a = Ysize - 1 ;
if (a < 0) a = 0 ;
if (b >= Xsize) b = Xsize - 1 ;
if (b < 0) b = 0 ;
*tp = (stack_t) Images[c].pix[a][color][b] ;
break ;
case OP_CLVAL : a = *--sp ; /* y */
b = *--sp ; /* x */
tp = sp-1 ;
c = (int) *tp ;
if (RangeCheck &&
(a > Xsize - 1 || a < 0 ||
b > Ysize - 1 || b < 0))
{
if (nrange++ == 0)
FPRINTF(stderr,
"Range err at (%d,%d) => %s[%d, %d]\n",
x, y, Images[c].str, b, a) ;
}
if (a >= Ysize) a = Ysize - 1 ;
if (a < 0) a = 0 ;
if (b >= Xsize) b = Xsize - 1 ;
if (b < 0) b = 0 ;
*tp = (stack_t)
&(Images[c].pix[a][color][b]) ;
break ;
case OP_PRVAL : {
int xval ;
int yval ;
a = *--sp ; /* Angle */
b = *--sp ; /* Radius */
xval = (int) (b * cos((double) DtoR(a)) +
Xsize / 2.0) ;
yval = (int) (- b * sin((double) DtoR(a)) +
Ysize / 2.0) ;
tp = sp - 1 ;
c = (int) *tp ;
if (RangeCheck &&
(xval < 0 || xval >= Xsize ||
yval < 0 || yval >= Ysize))
{
if (nrange++ == 0)
FPRINTF(stderr,
"Range err at (%d,%d) => %s{%d,%d} [%d,%d]\n",
x, y, Images[c].str, b, a, xval, yval) ;
}
if (xval < 0) xval = 0 ;
if (xval >= Xsize) xval = Xsize - 1 ;
if (yval < 0) yval = 0 ;
if (yval >= Ysize) yval = Ysize - 1 ;
*tp = (stack_t) Images[c].pix[yval][color][xval] ;
}
break ;
case OP_PLVAL : {
int xval ;
int yval ;
a = *--sp ; /* Angle */
b = *--sp ; /* Radius */
xval = (int) (b * cos((double) DtoR(a)) +
Xsize / 2.0) ;
yval = (int) (- b * sin((double) DtoR(a)) +
Ysize / 2.0) ;
tp = sp - 1 ;
c = (int) *tp ;
if (RangeCheck &&
(xval < 0 || xval >= Xsize ||
yval < 0 || yval >= Ysize))
{
if (nrange++ == 0)
FPRINTF(stderr,
"Range err at (%d,%d) => %s{%d,%d} [%d,%d]\n",
x, y, Images[c].str, b, a, xval, yval) ;
}
if (xval < 0) xval = 0 ;
if (xval >= Xsize) xval = Xsize - 1 ;
if (yval < 0) yval = 0 ;
if (yval >= Ysize) yval = Ysize - 1 ;
*tp = (stack_t) &(Images[c].pix[yval][color][xval]) ;
}
break ;
case OP_POW : a = *--sp ; /* Exponent */
tp = sp-1 ;
*tp = (stack_t)
pow((double) *tp, (double) a) ;
break ;
case OP_A :
#if NOMEM
*sp++ = (stack_t)
RtoD(atan2((double) y, (double) x)) + 0.5 ;
#else /* !NOMEM */
*sp++ = (stack_t) *ap ;
#endif /* !NOMEM */
break ;
case OP_R : *sp++ = (stack_t) *rp ;
break ;
case OP_SIN : tp = sp-1 ;
*tp = (stack_t)
(sin((double) DtoR(*tp)) * (double) Zmax) ;
break ;
case OP_COS : tp = sp-1 ;
*tp = (stack_t)
(cos((double) DtoR(*tp)) * (double) Zmax) ;
break ;
case OP_ATAN : a = *--sp ;
tp = sp-1 ;
*tp = (stack_t)
RtoD(atan2((double) *tp, (double) a)) ;
break ;
case OP_HYPOT : a = *--sp ;
tp = sp - 1 ;
*tp = (stack_t) hypot((double) *tp, (double) a) ;
break ;
case OP_ABS : tp = sp-1 ;
*tp = *tp < 0 ? - *tp : *tp ;
break ;
case OP_LOG : tp = sp-1 ;
*tp = (stack_t) log((double) *tp) ;
break ;
case OP_SQRT : tp = sp-1 ;
*tp = (stack_t) sqrt((double) *tp) ;
break ;
case OP_RAND : *sp++ = (stack_t) RANDOM ;
break ;
case OP_LSHIFT : dop(<<) ;
break ;
case OP_RSHIFT : dop(>>) ;
break ;
case OP_CONDIT : a = *--sp ;
CurrParse++ ;
if (!a)
CurrParse = &parsed[*CurrParse] ;
break ;
case OP_COLON : CurrParse = &parsed[CurrParse[1]] ;
break ;
default : if (*CurrParse < 127 && isprint(*CurrParse))
SPRINTF(ErrBuf, "run: unknown operator '%c' (%d)",
*CurrParse, *CurrParse) ;
else
SPRINTF(ErrBuf, "run: unknown operator %d",
*CurrParse) ;
error(ERR_SNARK) ;
return ;
}
}
++ap ;
++rp ;
}
}
#if SEQPAR
if (m_myid == 0)
#endif /* SEQPAR */
disp_percentdone(y * 100 / (Ysize-1)) ;
}
}
void
run()
{
int y ;
pixel_t ***linep ;
#if SEQPAR
static int parked = 0 ;
if (parked)
m_rele_procs() ;
m_fork(prun) ;
m_kill_procs() ; /* For some reason, parking doesn't work properly ...
m_park_procs() ;
parked = 1 ; /* so it can be released above */
#else /* ! SEQPAR */
prun() ;
#endif /* ! SEQPAR */
disp_percentdone(100) ; /* Can rely on '100' to terminate */
if (disp_active)
{
disp_imgstart() ;
for (linep = CurNew->pix, y = 0; y != Ysize; ++linep, ++y)
disp_putline(*linep, y) ;
disp_imgend() ;
}
SwapOldNew() ;
}
/* Convert the three RGB lines into one NTSC luma line, for display
* on grayscale devices. (Just pass pointer along if colors == 1)
*/
pixel_t*
ntsc_luma(lines)
pixel_t **lines ;
{
int x ;
static pixel_t *p = 0 ;
if (colors == 1) return(lines[0]) ;
if (p == NULL)
p = (pixel_t *) Emalloc((unsigned)Xsize * sizeof(pixel_t)) ;
for (x = 0; x < Xsize; x++)
p[x] = lines[0][x] * 0.299 + /* R */
lines[1][x] * 0.587 + /* G */
lines[2][x] * 0.114 ; /* B */
return(p) ;
}
Funky_Stuff
len=`wc -c < run.c`
if [ $len != 14422 ] ; then
echo error: run.c was $len bytes long, should have been 14422
fi
fi # end of overwriting check
if [ -f special.c ]
then
echo shar: will not over-write existing file special.c
else
echo shar: extracting 'special.c', 23621 characters
cat > special.c <<'Funky_Stuff'
/* @(#)special.c 1.5 91/08/20
*
* Special transformations used by the popi program.
*
* Popi was originally written by Gerard J. Holzmann - AT&T Bell Labs.
* This version is based on the code in his Prentice Hall book,
* "Beyond Photography - the digital darkroom," ISBN 0-13-074410-7,
* which is copyright (c) 1988 by Bell Telephone Laboratories, Inc.
*
* Permission is given to distribute these extensions, as long as these
* introductory messages are not removed, and no monies are exchanged.
*
* No responsibility is taken for any errors or inaccuracies inherent
* either to the comments or the code of this program, but if reported
* (see README file) then an attempt will be made to fix them.
*/
/* Special transformations from chapter 6 of BP.
*
* The way this is done is fairly nasty at the moment, but it does work.
*/
#include <sys/types.h>
#include <ctype.h>
#include <time.h>
#ifdef BSD
#include <sys/timeb.h>
#endif /* BSD */
#include "popi.h"
#include "lex.h"
#define GAMMA 7.5 /* Default gamma for matte() */
#define TILESIZE 25 /* Default tile size for tile() */
#define N 3 /* Default blur size for oil() */
#define New (CurNew->pix)
/* ANSI prototypes for local functions */
struct SRC *parseimg P((void)) ;
bool parsefname P((void)) ;
void CloseLog P((FILE **)) ;
void displayimg P((void)) ;
void debug P((void)) ;
void dolog P((void)) ;
void dosigned P((void)) ;
void freeimg P((void)) ;
void genepson P((void)) ;
void genps P((void)) ;
void imtrunc P((void)) ;
void list P((void)) ;
void matte P((void)) ;
void melt P((void)) ;
void oil P((void)) ;
void ofmt P((void)) ;
void readimg P((void)) ;
void shear P((void)) ;
void slice P((void)) ;
void tile P((void)) ;
void undo P((void)) ;
void verbose P((void)) ;
void writeimg P((void)) ;
struct SpecialOp
{
char *name, *notes ;
void (*func) P((void)) ;
} ;
static struct SpecialOp SpecialOps[] = { /* Also update popi.1 */
{ "debug", "", debug },
{ "display", "[+|-|image]", displayimg },
{ "free", "image", freeimg },
{ "genepson", "\"filename\" [image]", genepson },
{ "genps", "\"filename\" [image]", genps },
{ "help", "", help },
{ "list", "", list },
{ "logfile", "[+|-|\"filename\"]", dolog },
{ "matte", "[image [gamma]]", matte },
{ "melt", "[image]", melt },
{ "ofmt", "[+|-]", ofmt },
{ "oil", "[image]", oil },
{ "read", "\"filename\" [image]", readimg },
{ "shear", "[image]", shear },
{ "signed", "[+|-]", dosigned },
{ "slice", "[image]", slice },
{ "tile", "[image]", tile },
{ "truncate", "[+|-]", imtrunc },
{ "undo", "", undo },
{ "verbose", "[+|-]", verbose },
{ "version", "", version },
{ "write", "\"filename\" [image]", writeimg },
{ (char *) 0, (char *) 0, (void (*) P((void)) ) 0 }
} ;
/* Convenience function, since most of these routines have
* an image as their 1st parameter.
*/
static struct SRC *
parseimg()
{
lex() ;
if (lat == '\n' || lat == ')')
{
pushback(lat) ;
return CurOld ;
}
if (lat != T_INAME)
{
SPRINTF(ErrBuf, "Expected image name") ;
error(ERR_PARSE) ;
return (struct SRC *) 0 ;
}
return &Images[lexval] ;
}
static bool
parsefname()
{
lex() ;
if (lat == '\n') pushback(lat) ;
if (lat != T_FNAME)
{
SPRINTF(ErrBuf, "Expected file name") ;
error(ERR_PARSE) ;
return FALSE ;
}
return TRUE ;
}
static void
oil()
{
register int color, x, y ;
register int dx, dy ;
pixel_t mfp ;
static int *histo = 0 ;
struct SRC *srcp ;
pixel_t ***img ;
if ((srcp = parseimg()) == (struct SRC *) 0) return ;
img = srcp->pix ;
if (histo == (int *) 0 &&
(histo = (int *)
LINT_CAST(Emalloc((unsigned)Zsize * sizeof (int)))) == (int *) 0)
return ;
if (disp_active) disp_imgstart() ;
for (y = N; y < Ysize-N; y++)
{
for (x = N; x < Xsize-N; x++)
{
for (dx = 0; dx < Zsize; dx++) histo[dx] = 0 ;
for (dy = y-N; dy <= y+N; dy++)
for (dx = x-N; dx <= x+N; dx++)
for (color = 0; color < colors; ++color)
histo[img[dy][color][dx]]++ ;
for (dx = dy = 0; dx < Zsize; dx++)
if (histo[dx] > dy)
{
dy = histo[dx] ;
mfp = (pixel_t) dx ;
}
New[y][color][x] = mfp ;
}
if (disp_active) disp_putline(New[y], y) ;
disp_percentdone(y * 100 / (Ysize-1)) ;
}
if (disp_active) disp_imgend() ;
SwapOldNew() ;
}
static void
shear()
{
register int color, x, y, r ;
int dx, dy ;
static int *yshift = 0 ;
struct SRC *srcp ;
pixel_t ***img ;
if ((srcp = parseimg()) == (struct SRC *) 0) return ;
img = srcp->pix ;
if (yshift == 0 &&
(yshift = (int *)
LINT_CAST(Emalloc((unsigned)Xsize * sizeof(int)))) == 0)
return ;
if (disp_active) disp_imgstart() ;
for (x = r = 0; x < Xsize; x++)
{
if (RANDOM % Zsize < 128) r-- ;
else r++ ;
yshift[x] = r ;
}
for (y = 0; y < Ysize; y++)
{
for (color = 0; color < colors; color++)
{
if (RANDOM % Zsize < 128) r-- ;
else r++ ;
for (x = 0; x < Xsize; x++)
{
dx = x + r ;
dy = y + yshift[x] ;
if (dx >= Xsize || dy >= Ysize || dx < 0 || dy < 0)
continue ;
New[y][color][x] = img[dy][color][dx] ;
}
}
if (disp_active) disp_putline(New[y], y) ;
disp_percentdone(y * 100 / (Ysize-1)) ;
}
if (disp_active) disp_imgend() ;
SwapOldNew() ;
}
static void
slice()
{
register int color, x, y, r ;
int dx, dy ;
struct SRC *srcp ;
pixel_t ***img ;
static int *xshift = 0 ;
static int *yshift = 0 ;
if ((srcp = parseimg()) == (struct SRC *) 0) return ;
img = srcp->pix ;
if (xshift == 0 &&
(xshift = (int *)
LINT_CAST(Emalloc((unsigned)Ysize * sizeof (int)))) == 0)
return ;
if (yshift == 0 &&
(yshift = (int *)
LINT_CAST(Emalloc((unsigned)Xsize * sizeof (int)))) == 0)
return ;
if (disp_active) disp_imgstart() ;
for (x = dx = 0 ; x < Xsize; x++)
{
if (dx == 0)
{
r = (RANDOM & 63) - 32 ;
dx = 8 + RANDOM & 31 ;
}
else dx-- ;
yshift[x] = r ;
}
for (y = dy = 0; y < Ysize; y++)
{
if (dy == 0)
{
r = (RANDOM & 63) - 32 ;
dy = 8 + RANDOM & 31 ;
}
else dy-- ;
xshift[y] = r ;
}
for (y = 0; y < Ysize; y++)
{
for (color = 0; color < colors; color++)
for (x = 0; x < Xsize; x++)
{
dx = x + xshift[y] ;
dy = y + yshift[x] ;
if (dx < Xsize && dy < Ysize && dx >= 0 && dy >= 0)
New[y][color][x] = img[dy][color][dx] ;
}
if (disp_active) disp_putline(New[y], y) ;
disp_percentdone(y * 100 / (Ysize-1)) ;
}
if (disp_active) disp_imgend() ;
SwapOldNew() ;
}
static void
tile()
{
register int color, x, y, dx, dy ;
int ox, oy, nx, ny ;
int TileSize = TILESIZE ;
struct SRC *srcp ;
pixel_t ***img ;
if ((srcp = parseimg()) == (struct SRC *) 0) return ;
img = srcp->pix ;
for (y = 0; y < Ysize-TileSize; y += TileSize)
{
for (color = 0; color < colors; color++)
for (x = 0; x < Xsize-TileSize; x += TileSize)
{
ox = (RANDOM & 31) - 16 ; /* Displacement. */
oy = (RANDOM & 31) - 16 ;
for (dy = y; dy < y+TileSize; dy++)
for (dx = x; dx < x+TileSize; dx++)
{
nx = dx + ox ;
ny = dy + oy ;
if (nx >= Xsize || ny >= Ysize || nx < 0 || ny < 0)
continue ;
New[ny][color][nx] = img[dy][color][dx] ;
}
}
disp_percentdone(y * 100 / (Ysize-1)) ;
}
if (disp_active)
{
disp_imgstart() ;
for (y = 0; y < Ysize; y++) disp_putline(New[y], y) ;
disp_imgend() ;
}
SwapOldNew() ;
}
/* Note: affects source image in situ.
* Buffers not swapped after processing.
*/
static void
melt()
{
register int color, x, y, k, NumPixels ;
pixel_t val ;
struct SRC *srcp ;
pixel_t ***img ;
if ((srcp = parseimg()) == (struct SRC *) 0) return ;
img = srcp->pix ;
NumPixels = Xsize * Ysize ;
for (k = 0; k < NumPixels; k++)
{
x = RANDOM % Xsize ;
y = RANDOM % (Ysize - 1) ;
for (color = 0; color < colors; color++)
while (y < Ysize-1 && img[y][x] <= img[y+1][x])
{
val = img[y][color][x] ;
img[y][color][x] = img[y+1][color][x] ;
img[y+1][color][x] = val ;
y++ ;
}
disp_percentdone(k * 100 / (NumPixels-1)) ;
}
if (disp_active)
{
disp_imgstart() ;
for (y = 0; y < Ysize; y++)
disp_putline(img[y], y) ;
disp_imgend() ;
}
}
static void
matte()
{
struct SRC *srcp ;
pixel_t ***img ;
double gamma ;
register color, x, y ;
static pixel_t *lookup = (pixel_t *) 0 ;
static double lastgamma = 0.0 ;
DEBUG((Debug, "matte()\n")) ;
if ((srcp = parseimg()) == (struct SRC *) 0) return ;
img = srcp->pix ;
lex() ;
if (lat == '\n' || lat == ')')
{
gamma = GAMMA ;
pushback(lat) ;
}
else gamma = lexval + lexfract ;
if (lookup == 0 &&
(lookup = (pixel_t *) Emalloc((unsigned) Zsize)) == (pixel_t *) 0)
return ;
if (lastgamma != gamma)
{
for (x = 0; x < Zsize; ++x)
lookup[x] = ((double)Zmax * pow(x / (double)Zmax, gamma) < 3.0)
? Zmax : 0 ;
lastgamma = gamma ;
}
if (disp_active) disp_imgstart() ;
for (y = 0; y < Ysize; y++)
{
for (color = 0; color < colors; color++)
for (x = 0; x < Xsize; x++)
New[y][color][x] = lookup[img[y][color][x]] ;
if (disp_active) disp_putline(New[y], y) ;
disp_percentdone(y * 100 / (Ysize-1)) ;
}
if (disp_active) disp_imgend() ;
}
static void
genps()
{
int x, y ;
FILE *ostr ;
struct SRC *srcp ;
pixel_t ***img, *ip ;
time_t time P((time_t *)) ;
time_t clock ;
#if unix
char *getlogin P((void)) ;
#endif /* unix */
if (!parsefname()) return ;
if ((ostr = EfopenW(text)) == NULL) return ;
if ((srcp = parseimg()) == (struct SRC *) 0) return ;
img = srcp->pix ;
clock = time((time_t *) 0) ;
FPRINTF(ostr, "%%!PS-Adobe-1.0\n") ;
FPRINTF(ostr, "%%%%Title: popi bit image '%s'\n", srcp->str) ;
FPRINTF(ostr, "%%%%DocumentFonts:\n") ;
FPRINTF(ostr, "%%%%Creator: popi\n") ;
FPRINTF(ostr, "%%%%CreationDate: %s", ctime(&clock)) ; /* Includes \n */
FPRINTF(ostr, "%%%%Pages: 1\n") ;
#if unix
FPRINTF(ostr, "%%%%For: %s\n", getlogin()) ;
#endif /* unix */
FPRINTF(ostr, "%%%%EndComments\n") ;
FPRINTF(ostr, "clippath pathbbox pop pop translate\n") ;
FPRINTF(ostr, "clippath pathbbox pop exch pop exch sub dup scale\n") ;
FPRINTF(ostr, "/picstr %d string def\n", Xsize) ;
FPRINTF(ostr, "/doimage {\n") ;
FPRINTF(ostr, "%d %d %d [ %d 0 0 -%d 0 %d ]\n",
Xsize, Ysize, BITSPERPIXEL, Xsize, Ysize, Ysize) ;
FPRINTF(ostr, "{currentfile picstr readhexstring pop}image}bind def\n") ;
FPRINTF(ostr, "%%%%EndProlog\n%%%%Page 0 0\ndoimage\n") ;
for (y = 0; y < Ysize; ++y)
{
ip = ntsc_luma((pixel_t **) &img[y]) ;
for (x = 0; x < Xsize; ++x)
{
if (x % 40 == 0) /* Formatting only */
PUTC('\n', ostr) ;
FPRINTF(ostr, "%02x", *ip++) ;
}
PUTC('\n', ostr) ;
}
FPRINTF(ostr, "showpage\n") ;
Efclose(ostr) ;
}
/* Although this is set up to use one particular graphics mode
* of a 24-pin printer, everything should be generic enough
* that it can be changed to work with a different graphics
* mode on an 8-pin printer, just by changing a few numbers.
*/
static void
genepson()
{
struct SRC *srcp ;
char *PinVals ;
pixel_t *PinThresh, ThreshStep ;
FILE *ostr ;
register int x ;
register pixel_t ***img ;
int y, yn ;
int pin ;
int BytesPerChunk, PinsPerPixel, BytesPerColumn ;
int yPixelsPerByte, xPinsPerPixel, yPinsPerPixel ;
if (parsefname() == 0) return ;
if ((ostr = EfopenW(text)) == NULL) return ;
if ((srcp = parseimg()) == (struct SRC *) 0) return ;
img = srcp->pix ;
/* Printer specific */
xPinsPerPixel = 2 ;
yPinsPerPixel = 2 ;
BytesPerColumn = 24 / BITSINBYTE ;
PinsPerPixel = xPinsPerPixel * yPinsPerPixel ;
BytesPerChunk = xPinsPerPixel * BytesPerColumn ;
yPixelsPerByte = BITSINBYTE / yPinsPerPixel ;
/* Must be whole number of pixels (y direction) per byte. */
assert(yPinsPerPixel * yPixelsPerByte == BITSINBYTE) ;
/* Reallocate these each time, as changing the print mode
* may change the sizes of these arrays.
*/
if ((PinVals = Emalloc((unsigned)BytesPerChunk)) == 0 ||
(PinThresh = (pixel_t *)
Emalloc((unsigned) PinsPerPixel * sizeof(pixel_t))) == 0)
return ;
ThreshStep = (pixel_t) (Zsize / (PinsPerPixel + 1)) ;
for (pin = 0; pin < PinsPerPixel; ++pin)
PinThresh[pin] = (pixel_t) ((pin + 1) * ThreshStep) ;
for (y = 0; y < Ysize; y = yn)
{
/* Printer specific */
/* This print line is width Xsize pixels, and (Xsize * xPinsPerPixel)
* pin positions (dots on the page).
* No. of dots vertical is (BytesPerColumn * BITSINBYTE)
* which is yPinsPerPixel times the no. of image scanlines.
*/
FPRINTF(ostr, "\033*%c%c%c",
39, /* 180 dpi in both directions */
(Xsize * xPinsPerPixel) % 256,
(Xsize * xPinsPerPixel) / 256) ;
for (x = 0; x < Xsize; ++x)
{
register int ycur ;
int ByteCount, xpin ;
char *dp ;
/* Clear the PinVals array */
for (ByteCount = 0, dp = PinVals; ByteCount < BytesPerChunk;
++ByteCount)
*dp++ = 0 ;
dp = PinVals ;
/* For each byte-sized row of the print head, collect 1 pixel width of data. */
for (ByteCount = 0, dp = PinVals, ycur = y;
ByteCount < BytesPerColumn; ++ByteCount, dp += xPinsPerPixel)
{
register unsigned char bit ;
yn = ycur + yPixelsPerByte ;
if (yn > Ysize) yn = Ysize ;
/* For the current byte row of the print-head (ie. yPixelsPerByte image
* scanlines), collect a pixel width of data.
*/
for (bit = 0x80; ycur < yn; ++ycur)
{
pixel_t val ;
int ypin ;
if (colors == 1) val = img[ycur][0][x] ; /* Grey level */
else /* Calculate NTSC luma */
val = img[ycur][0][x] * 0.299 + /* R */
img[ycur][1][x] * 0.587 + /* G */
img[ycur][2][x] * 0.114 ; /* B */
/* Now use an appropriate no. of pins to simulate the greyscale value. */
for (ypin = 0, pin = 0; ypin < yPinsPerPixel; ++ypin)
{
for (xpin = 0; xpin < xPinsPerPixel; ++xpin, ++pin)
if (val < PinThresh[pin]) dp[xpin] |= bit ;
bit >>= 1 ;
}
}
}
/* We have set up enough columns for a single pixel in the x direction.
* Now print them in the correct order.
*/
for (xpin = 0; xpin < xPinsPerPixel; ++xpin)
{
for (ByteCount = 0; ByteCount < BytesPerColumn; ++ByteCount)
PUTC(PinVals[ByteCount * xPinsPerPixel + xpin], ostr) ;
}
}
/* Printer specific */
FPRINTF(ostr, "\033J%c\r", 24);
}
Efclose(ostr) ;
free(PinVals) ;
free((char *) PinThresh) ;
}
static void
list()
{
showfiles() ;
}
/* :read "filename" [imagename] */
static void
readimg()
{
char filename[512] ;
char *imgname = (char *) 0 ;
if (parsefname() == 0) return ;
STRCPY(filename, text) ;
lex() ;
if (lat == '\n' || lat == ')')
{
pushback(lat) ;
}
else if (lat != T_NAME && lat != T_INAME)
{
SPRINTF(ErrBuf, "Expected image name") ;
error(ERR_PARSE) ;
}
else imgname = text ;
getpix(filename, imgname) ;
}
static void
newimg()
{
struct SRC *img ;
lex() ;
if (lat == T_INAME)
{
SPRINTF(ErrBuf, "Image named '%s' already exists", text) ;
error(ERR_PARSE) ;
return ;
}
if (lat != T_NAME)
{
SPRINTF(ErrBuf, "Expected name of new image") ;
error(ERR_PARSE) ;
return ;
}
/* Find an empty slot in the image array */
for (img = Images; img->pix != (pixel_t ***) 0; ++img) continue ;
if (img == &Images[nimages]) ++nimages ;
if ((img->pix = ImgAlloc()) == (pixel_t ***) 0 ||
(img->str = (char *)
Emalloc((unsigned int) (strlen(text)+1))) == (char *) 0)
{
img->pix = (pixel_t ***) 0 ;
return ;
}
STRCPY(img->str, text) ;
/* Swap newly created image with old */
{
pixel_t ***tmp ;
tmp = CurOld->pix ;
CurOld->pix = img->pix ;
img->pix = tmp ;
}
}
static void
writeimg()
{
struct SRC *img ;
if (parsefname() == 0) return ;
if ((img = parseimg()) == (struct SRC *) 0) return ;
putpix(img, text) ;
}
static void
freeimg()
{
struct SRC *srcp ;
if ((srcp = parseimg()) == (struct SRC *) 0) return ;
if (srcp == CurOld || srcp == CurNew)
{
SPRINTF(ErrBuf, "Cannot free 'old' or 'new'") ;
error(0) ;
return ;
}
ImgFree(srcp) ;
}
static void
displayimg()
{
pixel_t ***img ;
int y ;
lex() ;
if (lat == '+')
{
disp_active = 1 ;
return ;
}
if (lat == '-')
{
disp_active = 0 ;
return ;
}
if (lat == '\n')
{
pushback(lat) ;
img = CurOld->pix ;
}
else if (lat == T_INAME) img = Images[lexval].pix ;
else if (lat == T_NEW) img = CurNew->pix ;
else
{
SPRINTF(ErrBuf, "Expected +, - or image name") ;
error(ERR_PARSE) ;
return ;
}
disp_imgstart() ;
for (y = 0; y < Ysize; y++) disp_putline(img[y], y) ;
disp_imgend() ;
}
static void
CloseLog(filep)
FILE **filep ;
{
if (*filep == NULL) return ;
FPRINTF(*filep, "\n---\n") ;
FCLOSE(*filep) ;
*filep = NULL ;
}
void
OpenLog(filep)
FILE **filep ;
{
time_t time() ;
time_t clock ;
CloseLog(filep) ;
if ((*filep = fopen(LogFile, "a")) == NULL)
{
SPRINTF(ErrBuf,
"Can't open log file '%s' - logging is off", LogFile) ;
error(ERR_SYS) ;
return ;
}
clock = time((time_t *) 0) ;
FPRINTF(*filep, "==>> %s", ctime(&clock)) ; /* Includes '\n' */
}
static void
dolog()
{
static char *buf = (char *) 0 ;
lex() ;
if (lat == '+') OpenLog(&LogStr) ;
else if (lat == '-') CloseLog(&LogStr) ;
else if (lat == T_FNAME)
{
if (buf == (char *) 0 &&
(buf = Emalloc((unsigned int) 512)) == (char *) 0)
return ;
STRCPY(buf, text) ;
LogFile = buf ;
OpenLog(&LogStr) ;
}
else pushback(lat) ;
if (LogStr) PRINTF("Logging is active on file '%s'\n", LogFile) ;
else PRINTF("Logging is off\n") ;
}
static void
debug()
{
static char *buf = (char *) 0 ;
lex() ;
if (lat == '+') OpenLog(&Debug) ;
else if (lat == '-') CloseLog(&Debug) ;
else if (lat == T_FNAME)
{
if (buf == (char *) 0 &&
(buf = Emalloc((unsigned int) 512)) == (char *) 0)
return ;
STRCPY(buf, text) ;
LogFile = buf ;
OpenLog(&Debug) ;
}
else pushback(lat) ;
if (Debug) PRINTF("Logging is active on file '%s'\n", LogFile) ;
else PRINTF("Logging is off\n") ;
}
static char *HelpMsg[] = {
"binary ops: ** * / % + - << >> < > >= <= == != & ^ | && ||",
"funcs: sin(deg) cos(deg) atan(y, x) hypot(x, y)",
" log(val) sqrt(val) abs(val) rand()",
"values: x y r a X Y R A Z",
"special funcs",
"\t:list",
"\t:read \"filename\"",
"\t:write \"filename\"",
"\t:genps \"filename\" [image]",
"\t:genepson \"filename\" [image]",
"\t:create image",
"\t:free image",
"\t:display [image]",
"\t:display +|-",
"\t:ofmt +|-",
"\t:truncate +|-",
"\t:signed +|-",
"\t:undo",
"\t:run \"filename\"",
"\t:logfile \"filename\"",
"\t:version",
"\t:quit (also `q' and `exit')",
(char *) 0
} ;
void
help()
{
int i ;
PrStrs(HelpMsg) ;
FPRINTF(stderr, "\t?\n") ;
FPRINTF(stderr, "\tq\n") ;
FPRINTF(stderr, "\n") ;
for (i = 0; SpecialOps[i].name; i++)
FPRINTF(stderr, "\t:%-10s %s\n",
SpecialOps[i].name, SpecialOps[i].notes) ;
}
static void
undo()
{
SwapOldNew() ;
}
static void
verbose()
{
lex() ;
if (lat == '+') Verbose = 1 ;
else if (lat == '-') Verbose = 0 ;
else pushback(lat) ;
PRINTF("Verbose is %s\n", Verbose ? "on" : "off") ;
}
static void
imtrunc()
{
lex() ;
if (lat == '+') Truncate = 1 ;
else if (lat == '-') Truncate = 0 ;
else pushback(lat) ;
PRINTF("Truncation is %s\n", Truncate ? "on" : "off") ;
}
static void
dosigned()
{
lex() ;
if (lat == '+') signed_io = 1 ;
else if (lat == '-') signed_io = 0 ;
else pushback(lat) ;
PRINTF("Signed I/O is %s\n", signed_io ? "on" : "off") ;
}
static void
ofmt()
{
lex() ;
if (lat == '+') oldfmt = 1 ;
else if (lat == '-') oldfmt = 0 ;
else pushback(lat) ;
PRINTF("Old output format is %s\n", oldfmt ? "on" : "off") ;
}
void
special()
{
int i, cnt, len ;
struct SpecialOp *sp ;
DEBUG((Debug, "special\n")) ;
lex() ;
for (cnt = i = 0; SpecialOps[i].name; i++)
if (strncmp(text, SpecialOps[i].name, strlen(text)) == 0)
{
sp = &SpecialOps[i] ;
cnt++ ;
}
if (cnt > 1)
{
SPRINTF(ErrBuf, "Special operation '%s' ambiguous (", text) ;
for (i = 0; SpecialOps[i].name; i++)
if (strncmp(text, SpecialOps[i].name, strlen(text)) == 0)
{
strcat(ErrBuf, SpecialOps[i].name) ;
strcat(ErrBuf, ", ") ;
}
len = strlen(ErrBuf);
ErrBuf[len-2] = ')';
ErrBuf[len-1] = '\n';
error(ERR_PARSE) ;
while (lat != '\n') /* !!! KLUDGE !!! */
lex() ;
return ;
}
if (cnt < 1)
{
SPRINTF(ErrBuf, "Special operation '%s' unrecognised", text) ;
error(ERR_PARSE) ;
while (lat != '\n') /* !!! KLUDGE !!! */
lex();
return ;
}
DEBUG((Debug, "calling func '%s'\n", sp->name)) ;
(*(sp->func))() ;
if (lat != '\n') lex() ;
if (lat != '\n')
{
SPRINTF(ErrBuf, "Tokens after special command ignored") ;
error(ERR_WARN) ;
}
assert(lat == '\n') ;
}
Funky_Stuff
len=`wc -c < special.c`
if [ $len != 23621 ] ; then
echo error: special.c was $len bytes long, should have been 23621
fi
fi # end of overwriting check
if [ -f popi.icon ]
then
echo shar: will not over-write existing file popi.icon
else
echo shar: extracting 'popi.icon', 1933 characters
cat > popi.icon <<'Funky_Stuff'
/* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
*/
0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x8000,0x0000,0x0001,0x0001,
0x8000,0x0000,0x0001,0x7F81,0x8000,0x0000,0x0001,0x30C1,
0x8000,0x0000,0x0001,0x3061,0x8000,0x0000,0x0001,0x3061,
0x8000,0x0000,0x0001,0x3061,0x8000,0x0000,0x0001,0x30C1,
0x8000,0x7600,0x0001,0x3781,0x8000,0xDF80,0x0001,0x3001,
0x8001,0x76E8,0x0001,0x3001,0x8001,0xFF00,0x0001,0x3001,
0x8002,0x7BFC,0x0001,0x3001,0x8002,0xDE03,0x0001,0x3001,
0x800A,0xD5F8,0x0001,0x3001,0x804A,0xBF45,0xC001,0x7801,
0x801A,0xE97C,0x0001,0x0001,0x81D3,0xAFEB,0x6001,0x0001,
0x823F,0xFBBE,0x1001,0x0F81,0x82EF,0xEAFF,0xF401,0x11C1,
0x857F,0xABFF,0x8401,0x20E1,0x857F,0xE87F,0xF801,0x6061,
0x87FF,0x007F,0xFE01,0x6061,0x8BFF,0x000F,0xF801,0x6061,
0x8FFC,0x0005,0xFE01,0x6061,0x87FE,0x01FF,0xFF01,0x7041,
0x8FFB,0xF37F,0xFE01,0x3881,0x87EF,0xF1E0,0xFF81,0x1F01,
0x8FF8,0xF1FE,0xFF81,0x0001,0x8FFF,0xB110,0x5D01,0x0001,
0x87E2,0xD0C4,0x5FC1,0x0001,0x8FEA,0x0010,0x3FC1,0x77C1,
0x87A0,0xA045,0x1FC1,0x38E1,0x87F4,0xA030,0x5F81,0x3071,
0x87D2,0x8001,0x3F81,0x3031,0x85D6,0xC014,0xBF81,0x3031,
0x87F0,0x39C5,0xBF01,0x3031,0x87DE,0x8F85,0xFE01,0x3031,
0x83EA,0x3FF4,0x3E01,0x3021,0x83FC,0xA85D,0xF801,0x3841,
0x81F7,0xFFE5,0xB801,0x3F81,0x81FE,0xA005,0xF801,0x3001,
0x807E,0x9007,0xF001,0x3001,0x807F,0x96C3,0xF801,0x3001,
0x80FE,0x8A8F,0xFC01,0x3001,0x80FF,0xCBA2,0xFE01,0x7801,
0x80FF,0xD69F,0xFF01,0x0001,0x807F,0xD5D7,0xFC01,0x0001,
0x81FF,0xF77F,0xFC01,0x0601,0x80FF,0xFDDF,0xFE01,0x0601,
0x80FF,0xEFFE,0xFE01,0x0001,0x81FE,0xFFFD,0xFF81,0x0001,
0x87FE,0xFFFD,0xFFC1,0x1E01,0x9FEF,0xBFF5,0xABF1,0x0601,
0xBFFB,0x7FDF,0xFFFD,0x0601,0xFFCF,0xD7F3,0xC7FF,0x0601,
0xFFFF,0xFFDF,0xFFFF,0x0601,0xFFFF,0x6FF7,0xFFFF,0x0601,
0xFFFF,0xFFFF,0xFFFF,0x0601,0xFFFF,0xEFCF,0xFFFF,0x0601,
0xFFFF,0xFFFF,0xFFFF,0x0601,0xFFFF,0xFFFF,0xFFFF,0x1F81,
0xFFFF,0xFFFF,0xFFFF,0x0001,0xFFFF,0xFFFF,0xFFFF,0xFFFF
Funky_Stuff
len=`wc -c < popi.icon`
if [ $len != 1933 ] ; then
echo error: popi.icon was $len bytes long, should have been 1933
fi
fi # end of overwriting check
exit 0 # Just in case...