Scantool part 3(5) (shar)

Was a Sunny day gunnar at falcon.ericsson.se
Tue Jun 18 22:47:32 AEST 1991


#!/bin/sh
# this is scan.03 (part 3 of a multipart archive)
# do not concatenate these parts, unpack them in order with /bin/sh
# file notify.h continued
#
if test ! -r _shar_seq_.tmp; then
	echo 'Please unpack part 1 first!'
	exit 1
fi
(read Scheck
 if test "$Scheck" != 3; then
	echo Please unpack part "$Scheck" next!
	exit 1
 else
	exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
	echo 'x - still skipping notify.h'
else
echo 'x - continuing file notify.h'
sed 's/^X//' << 'SHAR_EOF' >> 'notify.h' &&
EXTERN_FUNCTION (Notify_error 	notify_remove_exception_func, (Notify_client nclient, Notify_func func, int fd));
EXTERN_FUNCTION (Notify_error	notify_remove_input_func, (Notify_client nclient, Notify_func func, int fd));
EXTERN_FUNCTION (Notify_error 	notify_remove_itimer_func, (Notify_client nclient, Notify_func func, int which));
EXTERN_FUNCTION (Notify_error	notify_remove_output_func, (Notify_client nclient, Notify_func func, int fd));
EXTERN_FUNCTION (Notify_error 	notify_remove_signal_func, (Notify_client nclient, Notify_func func, int signal, Notify_signal_mode mode));
EXTERN_FUNCTION (Notify_error 	notify_remove_wait3_func, (Notify_client nclient, Notify_func func, int pid));
EXTERN_FUNCTION (Notify_func 	notify_set_prioritizer_func, (Notify_client nclient, Notify_func func));
EXTERN_FUNCTION (Notify_func 	notify_set_scheduler_func, (Notify_func nclient));
EXTERN_FUNCTION (Notify_error 	notify_signal, (Notify_client nclient, int sig));
EXTERN_FUNCTION (Notify_error 	notify_wait3, (Notify_client nclient));
X
extern	Notify_error	notify_errno;
X
/*
X * FD manipulation functions
X */
X
EXTERN_FUNCTION (int 		ntfy_fd_cmp_and, (fd_set *a, fd_set *b));
EXTERN_FUNCTION (int 		ntfy_fd_cmp_or, (fd_set *a, fd_set *b));
EXTERN_FUNCTION (int 		ntfy_fd_anyset, (fd_set *a));
EXTERN_FUNCTION (fd_set *	ntfy_fd_cpy_or, (fd_set *a, fd_set *b));
EXTERN_FUNCTION (fd_set *	ntfy_fd_cpy_and, (fd_set *a, fd_set *b));
EXTERN_FUNCTION (fd_set *	ntfy_fd_cpy_xor, (fd_set *a, fd_set *b));
X
/*
X * Debugging Utility 
X */
X
EXTERN_FUNCTION (void 		notify_dump, (Notify_client nclient, Notify_dump_type type, FILE * file));
X
#endif ~_NOTIFY_MIN_SYMBOLS
X
#endif	xview_notify_DEFINED
SHAR_EOF
echo 'File notify.h is complete' &&
chmod 0644 notify.h ||
echo 'restore of notify.h failed'
Wc_c="`wc -c < 'notify.h'`"
test 12908 -eq "$Wc_c" ||
	echo 'notify.h: original size 12908, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= patchlevel.h ==============
if test -f 'patchlevel.h' -a X"$1" != X"-c"; then
	echo 'x - skipping patchlevel.h (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting patchlevel.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'patchlevel.h' &&
X
/*  @(#)patchlevel.h 1.4 90/04/10
X *
X *  Current patchlevel for this version of scantool.
X *
X *  Copyright (c) Rich Burridge.
X *                Sun Microsystems, Australia - All rights reserved.
X *
X *  Permission is given to distribute these sources, as long as the
X *  copyright messages are not removed, and no monies are exchanged.
X *
X *  No responsibility is taken for any errors or inaccuracies inherent
X *  either to the comments or the code of this program, but if
X *  reported to me, then an attempt will be made to fix them.
X */
X
#define  PATCHLEVEL  3
SHAR_EOF
chmod 0644 patchlevel.h ||
echo 'restore of patchlevel.h failed'
Wc_c="`wc -c < 'patchlevel.h'`"
test 563 -eq "$Wc_c" ||
	echo 'patchlevel.h: original size 563, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= scan.1 ==============
if test -f 'scan.1' -a X"$1" != X"-c"; then
	echo 'x - skipping scan.1 (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting scan.1 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'scan.1' &&
.\" @(#)scan.1 1.3 90/04/03
.TH SCAN 1L "2 April 1990"
.SH NAME
scan \- a batch type program to scan images using a Microtek MS300A scanner.
.SH SYNOPSIS
.B "scan
[
.B -b
.I brightness
]
[
.B -c
.I contrast
]
[
.B -d
.I "data transfer mode"
]
[
.B -f
.I x1 y1 x2 y2
]
[
.B -g
.I grain
]
[
.B -m
.I mode
]
[
.B -p
.I picname
]
[
.B -r
.I resolution
]
[
.B -s
.I speed
]
[
.B -t
.I ttyport
]
[
.B -v
]
.SH DESCRIPTION
.I Scan
is the program called by
.I scantool
to allow a user to scan a document using a Microtek MS300A scanner, and
turn the resulting image into a Sun rasterfile. This program could actually
be run on it's own, or through a frontend shell script, but there are a
plethora of command line options that need to be passed to the program, so
it is probably easier to run it automatically using
.I scantool.
.LP
.I Scan
can exit with a variety of different status values, a non zero value indicating
an error of some kind. There error values are:
.TP
.B "1"
Cannot open the tty port.
.TP
.B "2"
Cannot open the temporary image file.
.TP
.B "3"
Cannot open raster header file.
.TP
.B "4"
Scanner not responding aborting this scan.
.TP
.B "5"
Invalid command line argument.
.TP
.B "100 + 0xnn"
Scanning error 0xnn was received from the scanner. This scan is aborted.
.TP
.B "200 + n"
The
.I scan
program received signal
.I n
.SH OPTIONS
.TP
.BI \-b " brightness"
Brightness value. There are 14 brightness values to choose from, ranging from
1 (-24% darker) to 14 (+28% lighter).
.TP
.BI \-c " contrast"
Contrast value. There are 14 contrast values to choose from, ranging from
1 (-24% lower) to 14 (+28% higher).
.TP
.BI \-d " data transfer method"
Data transfer method. This is the form in which data is transfer between
the scanner and the Sun. Currently this option can take two value; 0 is
uncompressed and 1 (the default) is compressed.
.TP
.BI \-f " x1 y1 x2 y2"
Scanning frame. The frame is the area to be scanned. This option needs the
two coordinate pairs; the top left of the scanning frame, and the bottom
right. These values are expressed in 1/8" increments.
.TP
.BI \-g " grain"
Grain value. There are twelve levels of grain to choose from, ranging from
0 (grain size: 8x8, grey levels: 33) to 11 (grain size: 2x2, grey levels 5).
.TP
.BI \-m " mode"
The scanner can operate in two modes; line art mode (value 0; the default) and
halftone mode (value 1).
.TP
.BI \-p " picname"
Output picture name. This is the name of the file which will contain the
scaned image in Sun rasterfile output format. By default, the name of the
file in NoName.rf.
.TP
.BI \-r " resolution"
Resolution value. There are 16 resolution values to choose from, ranging from
0 (300 dpi, scale full size) to 15 (75 dpi, scale 25%).
.TP
.BI \-s " speed"
Speed of the serial connection between the scanner and the Sun. A value of
0 is 960 baud. A value of 1 (the default) is 1920 baud.
.TP
.BI \-t " tty port"
This is the tty port to use. By default this is the Sun's A port (value 0).
It is also possibly to use the Sun's B port (value 1).
.TP
.B \-v
Version number of this release of the
.I scan
program. The third number is the current patch level.
.SH FILES
.TP
/usr/local/lib/scantool/black.codes
.TP
/usr/local/lib/scantool/white.codes
.SH AUTHOR
Rich Burridge,        Domain: richb at Aus.Sun.COM
.nf
PHONE: +61 2 413 2666   Path: {uunet,mcvax,ukc}!munnari!sunaus.oz!richb
.fi
SHAR_EOF
chmod 0644 scan.1 ||
echo 'restore of scan.1 failed'
Wc_c="`wc -c < 'scan.1'`"
test 3375 -eq "$Wc_c" ||
	echo 'scan.1: original size 3375, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= scan.c ==============
if test -f 'scan.c' -a X"$1" != X"-c"; then
	echo 'x - skipping scan.c (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting scan.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'scan.c' &&
X
/*  @(#)scan.c 1.4 90/04/04
X *
X *  Program which will read a scanned image from a Microtek
X *  MS-300A scanner and convert it to a Sun rasterfile.
X *
X *  Copyright (c) Rich Burridge.
X *                Sun Microsystems, Australia - All rights reserved.
X *
X *  Permission is given to distribute these sources, as long as the
X *  copyright messages are not removed, and no monies are exchanged.
X *
X *  No responsibility is taken for any errors or inaccuracies inherent
X *  either to the comments or the code of this program, but if
X *  reported to me, then an attempt will be made to fix them.
X */
X
#include <stdio.h>
#include <strings.h>
#include <signal.h>
#include <sgtty.h>
#include <rasterfile.h>
#include <sys/time.h>
#include <sys/types.h>
#include "patchlevel.h"
#include "scan.h"
X
char cksum ;               /* Packets checksum. */
char cntbytes ;            /* Number of count bytes received. */
char finalimage[MAXLINE] ; /* Name of uncompressed image file. */
char from_rs[BUFSIZE] ;    /* Data received from the RS232. */
char line[MAXLINE] ;
char picname[MAXLINE] ;    /* Picture name for rasterfile output. */
char progname[MAXLINE] ;   /* Name of this program. */
char rscksum ;             /* RS232 read packet checksum. */
char rsdata[BUFSIZE] ;     /* Latest packet to/from the scanner. */
char rsrhold = XON ;       /* RS232 host hand shaking state. */
char rsrstate = RSSOR ;    /* State of RS232 read automation. */
char rsrtype ;             /* Record type received. */
char rswstate ;            /* RS232 write acknowledgement state. */
char scantype[MAXLINE] ;   /* Scanner details. */
char temphead[MAXLINE] ;   /* Temporary filename for header file. */
char tempimage[MAXLINE] ;  /* Temporary filename for saved scanned data. */
X
int brightness ;           /* Brightness value. */
int cancel ;               /* Indicates if should cancel current scan. */
int complete ;             /* Indicates if scanning is completed. */
int contrast ;             /* Contrast value. */
int error ;                /* Has an error report has been received? */
int fd = -1 ;              /* File descriptor for RS232 line. */
int finished ;             /* Indicates if we have finished uncompressing. */
int fwidth ;               /* Final width of rasterfile. */
int height ;               /* Height in scan lines of raster file image. */
int pic_compressed = 0 ;   /* Whether any picture data was compressed. */
int pkt_started = 0 ;      /* Is a data packet coming from the scanner? */
int pktdone ;              /* Indicates if a complete packet received. */
int rc ;                   /* Current character from scanned file. */
int rcount ;               /* Count of bit position within read character. */
int rscnt ;                /* Number of data bytes to read. */
int rsptr ;                /* Character buffer pointer. */
int wc ;                   /* Current character to write to final image file. */
int wcount ;               /* Count of bit position within write character. */
int width ;                /* Width in pixels of rasterfile image. */
int grain ;                /* Grain value. */
int resolution ;           /* Resolution value. */
int retval ;               /* This programs exit status. */
int rf ;                   /* File descriptor for raster image. */
X
int switches[4] =
X      {
X        0,                 /* Mode (Line Art). */
X        1,                 /* Data Transfer (Compressed). */
X        0,                 /* Serial Port (A). */
X        1                  /* Baud Rate (19200). */
X      } ;
X
int framevals[4] =            /* Initial frame in 1/8th inch intervals. */
X      {
X        16,                /* X1. */
X        16,                /* Y1. */
X        48,                /* X2. */
X        48,                /* Y2. */
X     } ;
X
FILE *rd ;                 /* File descriptor for input files. */
FILE *wd ;                 /* File descriptor for final image. */
X
#ifdef NO_4.3SELECT
int readmask ;                /* File descriptors with outstanding reads. */
#else
fd_set readmask ;             /* Readmask used in select call. */
#endif NO_4.3SELECT
X
struct timeval timeout = { MAXTIME, 0 } ;
X
struct code *whites[16] ;   /* White initial starting pointers. */
struct code *blacks[4] ;    /* Black initial starting pointers. */
X
X
/*  The scan program can exit is a variety of ways. These are:
X *
X *  0          - successful   - image saved in picname.
X *  1          - unsuccessful - cannot open ttyline.
X *  2          - unsuccessful - cannot open temporary image file.
X *  3          - unsuccessful - cannot open raster header file.
X *  4          - unsuccessful - scanner not responding. Aborting this scan.
X *  5          - unsuccessful - invalid command line argument.
X *  100 + 0xnn - unsuccessful - scanning error 0xnn received. Scan aborted.
X *  200 + n    - unsuccessful - scan program terminated with signal n.
X *
X *  It is upto the calling program or shell script to display the
X *  appropriate message back to the user.
X */
X
main(argc, argv)
int argc ;
char *argv[] ;
{
X  retval = 0 ;
X  set_signals() ;              /* Set up a signal handler. */
X  STRCPY(progname, argv[0]) ;  /* Save program name. */
X  get_options(argc, argv) ;    /* Extract scanning parameters. */
X  do_scan() ;                  /* Perform a scan using given parameters. */
X  exit(retval) ;
}
X
X
SIGRET
do_exit(sig)   /* Signal received; exit gracefully. */
int sig ;
{
X  char outval ;
X
X  if (fd != -1)     /* Terminate the scan properly, if started. */
X    {
X      outval = ETX ;
X      WRITE(fd, &outval, 1) ;
X      CLOSE(fd) ;
X    }
X  exit(200 + sig) ;
}
X
X
do_handshake(value)            /* Send RS232 handshake XON/XOFF. */
char value ;
{
X  WRITE(fd, &value, 1) ;
X  rsrhold = value ;
}
X
X
do_scan()                      /* Perform a scan using given parameters. */
{
X  char c ;                     /* Next character for RS232 output. */
X
X  pic_compressed = 0 ;
X  height = 0 ;
X  error = 0 ;                           /* Set to 1 on error. */
X  if (open_temp_file() < 0) return ;    /* Open file for raster image. */
X  if (init_rs_port(SERIAL_PORT, BAUD_RATE) < 0) return ;
X 
/* Set scanning parameters. */
X  if (make_packet('!', 1, 0) < 0) return ;    /* Get scanner model number. */
X  if (make_packet('X', 1, 0) < 0) return ; ;  /* Reset scanning parameters. */
X
X  if (make_packet('C', 2, DATA_TRANSFER) < 0) return ;
X
X  if (MODE)
X    {
X      if (make_packet('H', 2, 0) < 0) return ;
X    }
X  else if (make_packet('T', 2, 0) < 0) return ;
X
X  if (make_packet('G', 2, grain) < 0) return ;       
X  if (make_packet('B', 2, brightness) < 0) return ; 
X  if (make_packet('K', 2, contrast) < 0) return ;  
X  if (make_packet('R', 2, resolution+16) < 0) return ;
X
X  if (make_frame_packet() < 0) return ;
X  if (make_packet('S', 1, 0) < 0) return ;     /* Send a start scan packet. */ 
X  complete = 0 ;
X  cancel = 0 ;
X  for (;;)
X    {
X 
#ifdef NO_4.3SELECT
X      readmask = 1 << fd ;
X      SELECT(32, &readmask, (int *) 0,(int *) 0, &timeout) ;
X      if (readmask & (1 << fd))
#else
X      FD_ZERO(&readmask) ;
X      FD_SET(fd, &readmask) ;
X      SELECT(FD_SETSIZE, &readmask, (fd_set *) 0, (fd_set *) 0, &timeout) ;
X      if (FD_ISSET(fd, &readmask))
#endif NO_4.3SELECT
X
X        read_rs232() ;
X      else
X        { 
X          if (rsrhold == XOFF) do_handshake(XON) ;
X          if (pkt_started)
X            {
X              c = NAK ;
X              WRITE(fd, &c, 1) ;
X              rsrstate = RSSOR ;
X              pkt_started = 0 ;
X            }
X        }    
X      if (complete || error || cancel) break ;
X    }
X  CLOSE(rf) ;                     /* Close temporary image file. */
X  if (!error)
X    {
X      save_picture() ;            /* Create Sun rasterfile picture. */
X      retval = 0 ;                /* Successful exit - image saved. */
X    }
X  else UNLINK(tempimage) ;
X  CLOSE(fd) ;
}
X
X
get_options(argc, argv)        /* Extract command line options. */
int argc ;
char *argv[] ;
{
X  char next[MAXLINE] ;    /* The next command line parameter. */
X
X  INC ;
X  while (argc > 0)
X    {
X      if (argv[0][0] == '-')
X        switch (argv[0][1])
X          {
X            case 'c' : INC ;                         /* Contrast. */
X                       getparam(next, argv, "-c needs contrast value") ;
X                       contrast = atoi(next) ;
X                       break ;
X            case 'b' : INC ;                         /* Brightness. */
X                       getparam(next, argv, "-b needs brightness value") ;
X                       brightness = atoi(next) ;
X                       break ;
X            case 'd' : INC ;                         /* Data transfer. */
X                       getparam(next, argv, "-d needs data transfer value") ;
X                       switches[DATA_TRANSFER] = atoi(next) ;
X                       break ;
X            case 'f' : INC ;                         /* Frame. */
X                       getparam(next, argv, "-f needs X1 coordinate") ;
X                       framevals[X1] = atoi(next) ;
X                       INC ;
X                       getparam(next, argv, "-f needs Y1 coordinate") ;
X                       framevals[Y1] = atoi(next) ;
X                       INC ;
X                       getparam(next, argv, "-f needs X2 coordinate") ;
X                       framevals[X2] = atoi(next) ;
X                       INC ;
X                       getparam(next, argv, "-f needs Y2 coordinate") ;
X                       framevals[Y2] = atoi(next) ;
X                       break ;
X            case 'g' : INC ;                         /* Grain. */
X                       getparam(next, argv, "-g needs grain value") ;
X                       grain = atoi(next) ;
X                       break ;
X            case 'm' : INC ;                         /* Mode. */
X                       getparam(next, argv, "-m needs mode value") ;
X                       switches[MODE] = atoi(next) ;
X                       break ;
X            case 'p' : INC ;                         /* Picture name. */
X                       getparam(picname, argv, "-p needs picture name") ;
X                       break ;
X            case 'r' : INC ;                         /* Resolution. */
X                       getparam(next, argv, "-r needs resolution value") ;
X                       resolution = atoi(next);
X                       break ;
X            case 's' : INC ;              /* Speed of RS232 connection. */
X                       getparam(next, argv, "-s needs speed value") ;
X                       switches[BAUD_RATE] = atoi(next) ;
X                       break ;
X            case 't' : INC ;                         /* Tty port. */
X                       getparam(next, argv, "-t needs tty port") ;
X                       switches[SERIAL_PORT] = atoi(next) ;
X                       break ;
X            case 'v' : FPRINTF(stderr, "%s version 1.4.%1d\n",
X                                       progname, PATCHLEVEL) ;
X                       break ;
X            case '?' : usage() ;
X          }
X      INC ;
X    }
}
X
X
getparam(s, argv, errmes)
char *s, *argv[], *errmes ;
{
X  if (*argv != NULL && argv[0][0] != '-') STRCPY(s, *argv) ;
X  else
X    { 
X      FPRINTF(stderr,"%s: %s as next argument.\n", progname, errmes) ;
X      exit(5) ;
X    }
}
X
X
init_rs_port(port, speed)              /* Initialise RS232 port. */
int port, speed ;
{
X  char ttyline[MAXLINE] ;
X  struct sgttyb sgttyb ;
X 
X  if (port) STRCPY(ttyline, "/dev/ttyb") ;
X  else      STRCPY(ttyline, "/dev/ttya") ;
X  if ((fd = open(ttyline,2)) < 0)
X    {
X      retval = 1 ;      /* Cannot open ttyline. */
X      return(-1) ;
X    }
X  GTTY(fd, &sgttyb) ;
X  sgttyb.sg_flags |= RAW ;
X  sgttyb.sg_flags &= ~(ECHO | CRMOD) ;
X  if (speed) sgttyb.sg_ispeed = sgttyb.sg_ospeed = EXTA ;
X  else       sgttyb.sg_ispeed = sgttyb.sg_ospeed = B9600 ;
X  STTY(fd, &sgttyb) ;             /* Implement tty line setup changes. */
X  return(0) ;
}
X
X
make_frame_packet()        /* Construct and send scanning frame packet. */
{
X  char cksum ;             /* For creating the packet checksum. */
X  int i ;
X
X  rsdata[0] = '\\' ;       /* Construct packet. */
X  rsdata[1] = 0x80 ;
X  rsdata[2] = 0x00 ;
X  rsdata[3] = 5 ;
X  rsdata[4] = 'F' ;
X  rsdata[5] = framevals[X1] ;
X  rsdata[6] = framevals[Y1] ;
X  rsdata[7] = framevals[X2] ;
X  rsdata[8] = framevals[Y2] ;
X  cksum = 0 ;
X  for (i = 1; i < 9; i++) cksum += rsdata[i] ;
X  rsdata[9] = (~cksum) + 1 ;
X  return(send_packet('F', 10)) ;
}
X
X
make_header(width, height)       /* Make Sun rasterfile header. */
int width, height ;
{
X  struct rasterfile header ;
X  FILE *hd ;                    /* File descriptor for header file. */
X
X  SPRINTF(temphead, "/usr/tmp/%s.header", mktemp("XXXXXX")) ;
X  if ((hd = fopen(temphead,"w")) == NULL)
X    {
X      retval = 3 ;              /* Can't open raster header file. */
X      return(-1) ;
X    }
X  header.ras_magic = 0x59a66a95 ;        /* Generate rasterfile header. */
X  header.ras_width = width ;
X  header.ras_height = height ;
X  header.ras_depth = 1 ;
X  header.ras_length = width * height ;
X  header.ras_type = RT_STANDARD ;
X  header.ras_maptype = RMT_RAW ;
X  header.ras_maplength = 0 ;
X  FWRITE((char *) &header, sizeof(struct rasterfile), 1, hd) ;
X  FCLOSE(hd) ;
X  return(0) ;
}
X
X
make_packet(ptype, count, value)   /* Sent a packet to the scanner. */
char ptype, count, value ;
{
X  char cksum ;                     /* For creating the packet checksum. */
X  int i ;
X  int len ;                        /* Length of this scanner packet. */
X
X  len = count + 5 ;
X  rsdata[0] = '\\' ;               /* Construct packet. */
X  rsdata[1] = 0x80 ;
X  rsdata[2] = 0x00 ;
X  rsdata[3] = count ;
X  rsdata[4] = ptype ;
X  if (count == 2) rsdata[5] = value ;
X  cksum = 0 ;
X  for (i = 1; i < len-1; i++) cksum += rsdata[i] ;
X  rsdata[len-1] = (~cksum) + 1 ;
X  return(send_packet(ptype, len)) ;
}
X
X
open_temp_file()          /* Open a temporary file for the scanned image. */
{
X  SPRINTF(tempimage, "/usr/tmp/%s.image", mktemp("XXXXXX")) ;
X  if ((rf = open(tempimage, 2)) < 0)
X    if ((rf = creat(tempimage, 0777)) < 0)
X      {
X        retval = 2 ;   /* Can't open temporary image file. */
X        return(-1) ;
X      }
X  return(0) ;
}
X
X
process_packet(ptype)     /* Process RS232 packet received. */
char ptype ;
{
X  int errorval ;          /* To extract error value. */
X  char outval ;           /* ACK or NAK value to be sent. */
X
X  if (rscksum == cksum)
X    {
X      outval = ACK ;
X      switch (ptype)
X        {
X          case 'D' : if ((rsrtype >> 5) & 1) pic_compressed++ ;
X                     height++ ;
X                     if (!((rsrtype >> 5) & 1)) rsptr = ((rsptr >> 2) << 2) ;
X                     WRITE(rf, from_rs, rsptr) ;
X                     width = rsptr * 8 ;
X                     break ;
X          case 'E' : outval = ETX ;    /* Complete scanning and eject paper. */
X                     WRITE(fd, &outval, 1) ;
X                     complete = 1 ;
X                     break ;
X          case '!' : STRNCPY(scantype, from_rs, rsptr) ;
X                     break ;
X          case '?' : errorval = (from_rs[1] & 0xFF) ;
X                     retval = 100 + errorval ;  /* Scanning error received. */
X                     printf("Error=0x%x",errorval);
X                     outval = ETX ;
X                     WRITE(fd, &outval, 1) ;
X                     error = 1 ;
X        }
X    }    
X  else outval = NAK ;
X  WRITE(fd, &outval, 1) ;        /* Send ACK or NAK. */
X  pktdone = 1 ;
}
X
X
read_rs232()      /* Read upto end of next packet. */
{
X  char c ;        /* Next character read from RS232. */
X  int count ;     /* Number of RS232 characters to read. */
X  int i ;
X
X  IOCTL(fd,(int) FIONREAD,(char *) &count) ;   /* Any data to read. */
X  if (count > MAXREAD) do_handshake(XOFF) ;
X  else if (count < 20 && rsrhold == XOFF) do_handshake(XON) ;
X  if (!count) return ;                         /* NO: exit routine. */
X  for (i = 0; i < count; i++)
X    {
X      READ(fd, &c, 1) ;                        /* Read next character. */
X      if (rsrstate == RSSOR && (c == ACK || c == NAK)) rswstate = c ;
X      else
X        switch (rsrstate)
X          {
X            case RSSOR   : rscksum = 0 ;
X                           if (c == SOR) rsrstate = RSRTYPE ;
X                           break ;
X            case RSRTYPE : rsrtype = c ;
X                           rscksum += c ;
X                           cntbytes = 0 ;
X                           rscnt = 0 ;
X                           rsrstate = RSCOUNT ;
X                           break ;
X            case RSCOUNT : rscksum += c ;
X                           rscnt = rscnt*256 + c ;
X                           if (++cntbytes == 2)
X                             {
X                               rsrstate = RSDATA ;
X                               rsptr = 0 ;
X                             }
X                           pkt_started = 1 ;
X                           break ;
X            case RSDATA  : from_rs[rsptr++] = c ;  /* Save data character. */
X                           rscksum += c ;
X                           if (!--rscnt) rsrstate = RSCKSUM ;
X                           break ;
X            case RSCKSUM : rscksum = (~rscksum) + 1 ;
X                           cksum = c ;
X                           if (rsrtype >> 7) process_packet(from_rs[0]) ;
X                           else process_packet('D') ;
X                           pkt_started = 0 ;
X                           rsrstate = RSSOR ;
X                           return ;
X          }
X    }
}
X
X
save_picture()    /* Combine header file and image to make a Sun rasterfile. */
{
X  char line[MAXLINE] ;          /* For constructing the system command. */
X
X  if (pic_compressed)
X    {
X      initialise_white("white.codes") ;
X      initialise_black("black.codes") ;
X      uncompress(tempimage) ;
X    }
X  else
X    { 
X      if (!make_header(width, height))   /* Write out Sun rasterfile header. */
X        {
X          SPRINTF(line, "cat %s %s > %s", temphead, tempimage, picname) ;
X          SYSTEM(line) ;                 /* Create Sun rasterfile. */
X          UNLINK(temphead) ;             /* Remove header file. */
X        }
X      UNLINK(tempimage) ;                /* Remove image file. */
X    }
}
X
X
send_packet(ptype, len)
char ptype,len ;
{
X  int done ;        /* Packet read or ACK/NAK found. */
X  int i ;
X
X  for (i = 0; i < MAXRETRIES; i++)
X    {
X      WRITE(fd, rsdata, len) ;
X      rswstate = NOANSWER ;
X      pktdone = 0 ;
X      done = 0 ;
X      do
X        {
#ifdef NO_4.3SELECT
X          readmask = 1 << fd ;
X          SELECT(32, &readmask, (int *) 0, (int *) 0, &timeout) ;
X          if (readmask & (1 << fd))
#else
X          FD_ZERO(&readmask) ;
X          FD_SET(fd, &readmask) ;
X          SELECT(FD_SETSIZE, &readmask, (fd_set *) 0, (fd_set *) 0, &timeout) ;
X          if (FD_ISSET(fd, &readmask))
#endif NO_4.3SELECT
X            {
X              read_rs232() ;
X              switch (ptype)
X                {
X                  case '!' : if (pktdone) done = 1 ;
X                             break ;
X                  default  : if (rswstate == ACK || rswstate == NAK) done = 1 ;
X                }
X              if (done) break ;
X            }
X          else break ;
X        }
X      while (!done) ;
X      if (rswstate == ACK) return(0) ;
X    }
X  retval = 4 ;   /* Scanner not responding. Aborting this scan. */
X  CLOSE(rf) ;
X  return(-1) ;
}
X
X
set_signals()   /* Setup a signal handler for a range of signals. */
{
X  SIGNAL(SIGHUP,  do_exit) ;
X  SIGNAL(SIGQUIT, do_exit) ;
X  SIGNAL(SIGILL,  do_exit) ;
X  SIGNAL(SIGTRAP, do_exit) ;
X  SIGNAL(SIGIOT,  do_exit) ;
X  SIGNAL(SIGEMT,  do_exit) ;
X  SIGNAL(SIGFPE,  do_exit) ;
X  SIGNAL(SIGBUS,  do_exit) ;
X  SIGNAL(SIGSEGV, do_exit) ;
}
X
X
usage()
{
X  FPRINTF(stderr, "Usage: %s: [-b brightness] [-c contrast] ", progname) ;
X  FPRINTF(stderr, "[-d] [-f x1 y1 x2 y2] [-g grain] [-m] [-p picname]\n") ;
X  FPRINTF(stderr, "[-s] [-t] [-v] [-?] [-Wi] [-Wp x y] [-WP x y]\n") ;
X  exit(5) ;
}
SHAR_EOF
chmod 0644 scan.c ||
echo 'restore of scan.c failed'
Wc_c="`wc -c < 'scan.c'`"
test 19810 -eq "$Wc_c" ||
	echo 'scan.c: original size 19810, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= scan.h ==============
if test -f 'scan.h' -a X"$1" != X"-c"; then
	echo 'x - skipping scan.h (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting scan.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'scan.h' &&
X
/*  @(#)scan.h 1.3 90/04/03
X *
X *  Definitions used by scan.
X *
X *  Copyright (c) Rich Burridge.
X *                Sun Microsystems, Australia - All rights reserved.
X *
X *  Permission is given to distribute these sources, as long as the
X *  copyright messages are not removed, and no monies are exchanged.
X *
X *  No responsibility is taken for any errors or inaccuracies inherent
X *  either to the comments or the code of this program, but if
X *  reported to me, then an attempt will be made to fix them.
X */
X
#define  CLOSE       (void) close      /* To make lint happy. */
#define  FCLOSE      (void) fclose
#define  FPRINTF     (void) fprintf
#define  FWRITE      (void) fwrite
#define  GTTY        (void) gtty
#define  IOCTL       (void) ioctl
#define  PUTC        (void) putc
#define  READ        (void) read
#define  SELECT      (void) select
#define  SIGNAL      (void) signal
#define  SSCANF      (void) sscanf
#define  SPRINTF     (void) sprintf
#define  STRCPY      (void) strcpy
#define  STRNCPY     (void) strncpy
#define  STTY        (void) stty
#define  SYSTEM      (void) system
#define  UNLINK      (void) unlink
#define  WRITE       (void) write
X
char *malloc(), *mktemp() ;
X
#define  BUFSIZE        512     /* RS232 data buffer size. */
#define  ETX            3       /* End of scanning code for scanner. */
#define  INC            argc-- ; argv++ ;
#define  MAXLINE        80      /* Length of character strings. */
#define  MAXREAD        100     /* Maximum amount of outstanding data. */
#define  MAXRETRIES     5       /* Number of attempts to send packet. */
#define  MAXTIME        2       /* RS232 read timeout in seconds. */
#define  SOR            '\\'    /* Start of record character. */
#define  XOFF           19      /* Stop sending data. */
#define  XON            17      /* Start sending data again. */
#define  X1             0       /* Coordinate values within framevals. */
#define  Y1             1
#define  X2             2
#define  Y2             3
X
/* RS232 read automation states. */
#define  RSSOR       0            /* Start of packet. */
#define  RSRTYPE     1            /* Record type. */
#define  RSCOUNT     2            /* Data count. */
#define  RSDATA      3            /* Packet data. */
#define  RSCKSUM     4            /* Packet checksum. */
X
/* States for packet acknowledgement. */
#define  NOANSWER    '-'        /* No acknowledgement received. */
#define  ACK         6          /* Positive acknowledgement. */
#define  NAK         21         /* Negative acknowledgement. */
X
/* Abbreviations for box switch values. */
#define  MODE           switches[0]
#define  DATA_TRANSFER  switches[1]
#define  SERIAL_PORT    switches[2]
#define  BAUD_RATE      switches[3]
X
/* Color definitions used with uncompressing. */
#define  WHITE          4
#define  BLACK          2
X
#ifndef  SIGRET
#define  SIGRET         void
#endif /* SIGRET */
X
#ifndef LINT_CAST
#ifdef lint
#define LINT_CAST(arg)  (arg ? 0 : 0)
#else
#define LINT_CAST(arg)  (arg)
#endif lint
#endif LINT_CAST
X
struct code                     /* Huffman code record. */
X         {
X           struct code *next[2] ;
X           int value[2] ;
X         } ;
SHAR_EOF
chmod 0644 scan.h ||
echo 'restore of scan.h failed'
Wc_c="`wc -c < 'scan.h'`"
test 3171 -eq "$Wc_c" ||
	echo 'scan.h: original size 3171, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= scan_compress.c ==============
if test -f 'scan_compress.c' -a X"$1" != X"-c"; then
	echo 'x - skipping scan_compress.c (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting scan_compress.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'scan_compress.c' &&
X
/*  @(#)scan_compress.c 1.2 90/04/02
X *
X *  Routines for uncompressing a scanned file, which has been compressed
X *  using the CCITT Recommendation T.4 (modified Huffman code).
X *
X *  Copyright (c) Rich Burridge.
X *                Sun Microsystems, Australia - All rights reserved.
X *
X *  Permission is given to distribute these sources, as long as the
X *  copyright messages are not removed, and no monies are exchanged.
X *
X *  No responsibility is taken for any errors or inaccuracies inherent
X *  either to the comments or the code of this program, but if
X *  reported to me, then an attempt will be made to fix them.
X */
X
#include <stdio.h>
#include "scan.h"
#include "scan_extern.h"
X
X
initialise_white(filename)    /* Read white Make Up and Terminating Codes. */
char filename[MAXLINE] ;
{
X  char bitstring[MAXLINE] ;     /* This lines huffman encoded bit string. */
X  char line[MAXLINE] ;          /* Current line read from file. */
X  int bvalue, i, indexval, n, runlength ;
X  struct code *ptr ;            /* Current codes structure pointer. */
X
X  for (i = 0; i < 16; i++)
X    {
X      whites[i] = (struct code *) LINT_CAST(malloc(sizeof(struct code))) ;
X      whites[i]->next[0] = NULL ;
X      whites[i]->next[1] = NULL ;
X    }
X
X  if ((rd = fopen(filename,"r")) == NULL)
X    {
X      FPRINTF(stderr, "%s: can't open %s\n", progname, filename) ;
X      exit(1) ;
X    }
X
X  while (fgets(line, MAXLINE, rd) != NULL)
X    {
X      SSCANF(line, "%d %s", &runlength, bitstring) ;
X      n = 0 ;
X      indexval = 0 ;
X      for (i = 0; i < 4; i++)
X        {
X          bvalue = bitstring[n++] - '0' ;
X          indexval = (indexval << 1) + bvalue ;
X        }
X      ptr = whites[indexval] ;
X      for (i = n ; i < strlen(bitstring); i++)
X        {
X          if (ptr->next[bvalue] == NULL)
X            {
X              ptr->next[bvalue] = (struct code *) LINT_CAST(malloc(sizeof(struct code))) ;
X              ptr->next[bvalue]->next[0] = NULL ;
X              ptr->next[bvalue]->next[1] = NULL ;
X            }
X          ptr = ptr->next[bvalue] ;
X          bvalue = bitstring[i] - '0' ;
X        }
X      ptr->value[bvalue] = runlength ;
X    }
X  FCLOSE(rd) ;
}
X
X
initialise_black(filename)    /* Read black Make Up and Terminating Codes. */
char filename[MAXLINE] ;
{
X  char bitstring[MAXLINE] ;     /* This lines huffman encoded bit string. */
X  char line[MAXLINE] ;          /* Current line read from file. */
X  int bvalue, i, indexval, n, runlength ;
X  struct code *ptr ;            /* Current codes structure pointer. */
X
X  for (i = 0; i < 4; i++)
X    {
X      blacks[i] = (struct code *) LINT_CAST(malloc(sizeof(struct code))) ;
X      blacks[i]->next[0] = NULL ; 
X      blacks[i]->next[1] = NULL ; 
X    }
X 
X  if ((rd = fopen(filename,"r")) == NULL)
X    {
X      FPRINTF(stderr, "%s: can't open %s\n", progname, filename) ;
X      exit(1) ;
X    } 
X 
X  while (fgets(line, MAXLINE, rd) != NULL)
X    {
X      SSCANF(line, "%d %s", &runlength, bitstring) ;
X      n = 0 ;
X      indexval = 0 ;
X      for (i = 0; i < 2; i++)
X        {
X          bvalue = bitstring[n++] - '0' ;
X          indexval = (indexval << 1) + bvalue ;
X        }
X      ptr = blacks[indexval] ;
X      for (i = n ; i < strlen(bitstring); i++)
X        {
X          if (ptr->next[bvalue] == NULL)
X            {
X              ptr->next[bvalue] = (struct code *) LINT_CAST(malloc(sizeof(struct code))) ;
X              ptr->next[bvalue]->next[0] = NULL ;
X              ptr->next[bvalue]->next[1] = NULL ;
X            }
X          ptr = ptr->next[bvalue] ;
X          bvalue = bitstring[i] - '0' ;
X        } 
X      ptr->value[bvalue] = runlength ;
X    }   
X  FCLOSE(rd) ;
}
X
X
get_bitval()        /* Get next bit value from compressed scanned file. */
{
X  if (rcount == 8)
X    {
X      if ((rc = getc(rd)) == EOF)
X        {
X          finished = 1 ;
X          return(-1) ;
X        }
X      rcount = 0 ;
X    }
X  return((rc >> (7-rcount++)) & 1) ;
}
X
X
get_code(color)        /* Get next huffman code for this color. */
int color ;
{
X  int bvalue, i, indexval ;
X  struct code *ptr ;
X
X  indexval = 0 ;
X  for (i = 0; i < color; i++)
X    {
X      if ((bvalue = get_bitval()) == -1) return(-1) ;
X      indexval = (indexval << 1) + bvalue ;
X    }
X  if (color == WHITE) ptr = whites[indexval] ;
X  else ptr = blacks[indexval] ;
X  for (;;)
X    {
X      if (ptr->next[bvalue] == NULL) return(ptr->value[bvalue]) ;
X      ptr = ptr->next[bvalue] ;
X      if ((bvalue = get_bitval()) == -1) return(-1) ;
X    }
}
X
X
write_code(color, length)   /* Send uncompressed data to temporary file. */
int color, length ;
{
X  int i ;
X
X  for (i = 0; i < length; i++)
X    {
X      if (color == BLACK) wc |= (1 << 7 - wcount) ;
X      if (++wcount == 8)
X        {
X          PUTC(wc, wd) ;
X          wc = 0 ;
X          wcount = 0 ;
X        }
X    }
}
X
X
uncompress(filename)     /* Uncompress the scanned file using huffman codes. */
char filename[MAXLINE] ;
{
X  int rem, runlength ;
X
X  finished = 0 ;
X  if ((rd = fopen(filename, "r")) == NULL)
X    {
X      FPRINTF(stderr, "%s: can't open %s\n", progname, filename) ;
X      exit(1) ;
X    }
X  SPRINTF(finalimage, "/usr/tmp/%s.unc.image", mktemp("XXXXXX")) ;
X  if ((wd = fopen(finalimage, "w")) == NULL)
X    {
X      FPRINTF(stderr, "%s: can't open %s\n", progname, finalimage) ;
X      exit(1) ;
X    }
X
X  width = 0 ;
X  height = 0 ;
X  rcount = 8 ;            /* Force a character read. */
X  wcount = 0 ;
X  do
X    {
X      runlength = get_code(WHITE) ;
X      if (runlength != -1) width += runlength ;
X      if (finished) break ;
X      if (runlength == -1)
X        {
X          height++ ;
X          rem = width % 16 ;
X          if (rem) write_code(WHITE, rem) ;
X          fwidth = width + rem ;
X          if (!finished) width = 0 ;
X          rcount = 8 ;
X          continue ;
X        }
X      write_code(WHITE, runlength) ;
X      if (runlength >= 64)
X        {
X          runlength = get_code(WHITE) ;
X          if (runlength != -1) width += runlength ;
X          write_code(WHITE, runlength) ;
X        }
X
X      runlength = get_code(BLACK) ;
X      if (runlength != -1) width += runlength ;
X      if (finished) break ;
X      if (runlength == -1)
X        {
X          height++ ;
X          rem = width % 16 ;
X          if (rem) write_code(WHITE, rem) ;
X          fwidth = width + rem ;
X          if (!finished) width = 0 ;
X          rcount = 8 ;
X          continue ;
X        }
X      write_code(BLACK, runlength) ;
X      if (runlength >= 64)
X        {
X          runlength = get_code(BLACK) ;
X          if (runlength != -1) width += runlength ;
X          write_code(BLACK, runlength) ;
X        }
X    }
X  while (!finished) ;
X  FCLOSE(rd) ;
X  FCLOSE(wd) ;
X  if (!make_header(fwidth, height))     /* Write out Sun rasterfile header. */
X    {
X      SPRINTF(line, "cat %s %s > %s", temphead, finalimage, picname) ;
X      SYSTEM(line) ;                    /* Create Sun rasterfile. */
X      UNLINK(temphead) ;                /* Remove header file. */
X    }
X  UNLINK(tempimage) ;
X  UNLINK(finalimage) ;
}
SHAR_EOF
chmod 0644 scan_compress.c ||
echo 'restore of scan_compress.c failed'
Wc_c="`wc -c < 'scan_compress.c'`"
test 6931 -eq "$Wc_c" ||
	echo 'scan_compress.c: original size 6931, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= scan_extern.h ==============
if test -f 'scan_extern.h' -a X"$1" != X"-c"; then
	echo 'x - skipping scan_extern.h (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting scan_extern.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'scan_extern.h' &&
X
/*  @(#)scan_extern.h 1.2 90/04/02
X *
X *  External variables used by the scan program.
X *
X *  Copyright (c) Rich Burridge.
X *                Sun Microsystems, Australia - All rights reserved.
X *
X *  Permission is given to distribute these sources, as long as the
X *  copyright messages are not removed, and no monies are exchanged.
X *
X *  No responsibility is taken for any errors or inaccuracies inherent
X *  either to the comments or the code of this program, but if
X *  reported to me, then an attempt will be made to fix them.
SHAR_EOF
true || echo 'restore of scan_extern.h failed'
fi
echo 'End of  part 3'
echo 'File scan_extern.h is continued in part 4'
echo 4 > _shar_seq_.tmp
exit 0



More information about the Alt.sources mailing list