Sun screendump to QMS laser printer filter
Don Gworek
uggworek at sunybcs.UUCP
Sun Dec 7 09:24:16 AEST 1986
Here is a filter for converting Sun screendump output to
QMS quic codes.
The filter takes advantage of the QMS data repeat commands
to reduce the printjob size by 65% on average. From 260 kb
to 90 kb on average, for a 900 by 1152 pixel rasterfile.
-------------------------- cut here -----------------------------------
# This is a shell archive. Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file". (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# screendump2qms.1 screendump2qms.c printer.h Makefile
echo x - screendump2qms.1
sed -e 's/^X//' > "screendump2qms.1" << '//E*O*F screendump2qms.1//'
X.\" @(#)screendump2qms.1 1.1 (Don Gworek) 7/19/86
X.\" This document uses the troff(1) -man macros
X.TH SCREENDUMP2QMS 1 "19 July 1986" "" "Local UNIX Programmer's Manual"
X.SH NAME
Xscreendump2qms \- filter Sun screendump output to QMS printer codes
X.SH SYNOPSIS
X.B screendump2qms
X[
X-l
X] [
Xrasterfile
X]
X.SH DESCRIPTION
XThis filter converts
X.I screendump(1)
Xoutput to printer codes for a QMS Laser printer. It reads
Xfrom standard input, or a file.
XThe image is printed in landscape mode. Printjobs average 90 kb
Xfor a 900 by 1152 pixel screendump.
X.PP
XThe
X-l option
Xdisables QMS data repeat commands. Instead, the screendump is
Xprinted in a ``long'' format, approximately 260 kb. The option will print
Xthe same image, but the raster by raster output could piped
Xto
X.I sed(1)
Xto yield an ascii-hex bitmap.
X.SH SEE ALSO
Xscreendump(1)
X.SH AUTHOR
XDon Gworek
//E*O*F screendump2qms.1//
echo x - screendump2qms.c
sed -e 's/^X//' > "screendump2qms.c" << '//E*O*F screendump2qms.c//'
X#ifndef lint
Xstatic char rcsid[] =
X "$Header: screendump2qms.c,v 1.1 86/08/30 22:14:33 gworek Exp $";
X#endif
X
X/*
X * screendump2qms - Filter SUN screendump into QMS quic code.
X *
X * Usage: screendump2qms [-l] [rasterfile]
X *
X * Option:
X * -l Don't use QMS data repeat commands.
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/file.h>
X#include <signal.h>
X
X#ifdef sun
X# include <rasterfile.h>
X#else
X# include "rasterfile.h"
X#endif
X
X#include "printer.h"
X
X#define STDIN_FDESC 0 /* stdin's file descriptor */
X#define BITSPERBYTE 8 /* number of bits per byte */
X#define TRUE 1
X#define FALSE 0
X
Xint count; /* count of bytes read */
Xint total; /* total to read (ras_length) */
Xint longf = FALSE; /* Want printer codes in long format? */
X
Xchar *progname; /* who am i? */
Xchar *inputfile; /* where's my input from? */
X
Xunsigned char buf[BUFSIZ]; /* The input buffer */
X
Xint cleanup();
Xchar *rindex();
Xchar *ctime();
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X int f, n;
X struct rasterfile rh;
X
X progname = (progname = rindex(*argv, '/')) ? ++progname : *argv;
X/*
X * Parse args
X */
X for (argc--, argv++; (argc > 0) && (**argv == '-'); argc--, argv++)
X switch (*++(*argv)) {
X case 'l':
X longf = TRUE;
X break;
X default:
X usage();
X }
X/*
X * Open the raster file, or use standard input.
X */
X if (argc > 0) {
X inputfile = *argv;
X if ((f = open(*argv, O_RDONLY)) < 0) {
X perror(*argv);
X exit(1);
X }
X }
X else {
X inputfile = "stdin";
X f = STDIN_FDESC;
X }
X/*
X * Get the header information, and check that everything is okay.
X */
X if ((n = read(f, (char *) &rh, sizeof(struct rasterfile))) < 0) {
X perror(inputfile);
X exit(1);
X }
X if (n == 0)
X die_on_error("empty file");
X if (rh.ras_magic != RAS_MAGIC)
X die_on_error("bad magic number");
X if (rh.ras_type != RT_STANDARD)
X die_on_error("ras_type %d not RT_STANDARD", rh.ras_type);
X if (rh.ras_maptype != RMT_NONE)
X die_on_error("ras_maptype %d not RMT_NONE", rh.ras_maptype);
X if (rh.ras_depth != 1)
X die_on_error("depth %d != 1", rh.ras_depth);
X/*
X * Access, set, and check image parameters.
X */
X total = rh.ras_length;
X if (((rh.ras_width / BITSPERBYTE) * rh.ras_height) != rh.ras_length)
X die_on_error("calculated data length %d != ras_length %d",
X ((rh.ras_width / BITSPERBYTE) * rh.ras_height),
X rh.ras_length);
X/*
X * Set up some cleaning up
X */
X (void) signal(SIGHUP, cleanup);
X (void) signal(SIGINT, cleanup);
X (void) signal(SIGQUIT, cleanup);
X (void) signal(SIGTERM, cleanup);
X/*
X * Set up the printer
X */
X printf(RESETPRINTER);
X printf(STARTPRINTER);
X printf(MARGINSET);
X printf(BITMAPSTART, rh.ras_width);
X/*
X * Print out in long form, or with data repeat commands?
X */
X if (longf == TRUE)
X printlong(f, rh.ras_width / BITSPERBYTE);
X else
X printrepeat(f);
X/*
X * Clean up shop
X */
X printf(BITMAPEND);
X printf(NEWPAGE);
X if (count != rh.ras_length)
X fprintf(stderr, "warning: %d bytes read != ras_length %d",
X count, rh.ras_length);
X (void) close(f);
X}
X
X/*
X * Print in long format. Read a raster at a time, and print
X * it byte by byte.
X */
Xprintlong(f, rasterlen)
Xint f, rasterlen;
X{
X int i, n;
X
X if (rasterlen > BUFSIZ) {
X fprintf(stderr, "%s: printlong: Internal error. ", progname);
X fprintf(stderr, "Increase buffer size from %d to at least %d\n",
X BUFSIZ, rasterlen);
X exit(1);
X }
X for (count=0; (n = read(f, (char *) buf, rasterlen)) > 0; count += n) {
X for (i = 0; i < n; i++)
X printf(DEFFORMAT, buf[i]);
X printf("\n");
X }
X}
X
X/*
X * Read bytes, counting repeated values. If there are enough
X * repeats, use a data compression print command. Otherwise,
X * print the data as is.
X */
Xprintrepeat(f)
Xint f;
X{
X int i, n, rep;
X unsigned char lastb;
X
X/*
X * Start things off.
X */
X if ((n = read(f, (char *) buf, BUFSIZ)) <= 0)
X return;
X i = 0;
X count = n;
X rep = 1;
X lastb = buf[0];
X/*
X * Read bytes until a different value is read.
X */
X for (;;) {
X if (++i >= n) {
X if ((n = read(f, (char *) buf, BUFSIZ)) <= 0)
X return;
X i = 0;
X count += n;
X }
X if (buf[i] == lastb) {
X if (rep < MAXREPEAT) {
X rep++;
X continue;
X }
X }
X/*
X * If the byte pattern didn't repeat long enough, print out
X * that count of bytes. Otherwise, print out the pattern
X * according to the correct repeat format.
X */
X if (rep < MINREPEAT)
X while (rep-- > 0)
X printf(DEFFORMAT, lastb);
X else
X switch (lastb) {
X case 0xFF:
X printf(BITSON, 2 * rep);
X break;
X case 0x00:
X printf(BITSOFF, 2 * rep);
X break;
X default:
X printf(BITSOFFON, rep, lastb);
X break;
X }
X lastb = buf[i];
X rep = 1;
X }
X}
X
X/*
X * Cleanup shop before you die
X */
Xcleanup()
X{
X printf(BITMAPEND);
X printf(NEWPAGE);
X fprintf(stderr, "%s: cleaning up. read %d of %d bytes.\n",
X progname, count, total);
X exit(1);
X}
X
X/*
X * Print an error message with the program and input file names,
X * and then die.
X */
X
X/* VARARGS */
Xdie_on_error(mesg, arg1, arg2)
Xchar *mesg;
X{
X fprintf(stderr, "%s: %s: ", progname, inputfile);
X fprintf(stderr, mesg, arg1, arg2);
X fprintf(stderr, ".\n");
X exit(1);
X}
X
X/*
X * How do you use this darn thing anyway?
X */
Xusage()
X{
X fprintf(stderr, "Usage: %s [-l] [rasterfile]", progname);
X exit(1);
X}
//E*O*F screendump2qms.c//
echo x - printer.h
sed -e 's/^X//' > "printer.h" << '//E*O*F printer.h//'
X/*
X * $Header: printer.h,v 1.6 86/07/19 12:47:17 gworek Exp $
X */
X
X/*
X * QMS quic code sequences are defined here
X */
X
X#define RESETPRINTER "ReSeTrEsEtReSeT\n"
X#define STARTPRINTER "^PY^-\n^F^ISYNTAX00000^ISTF00\n"
X#define MARGINSET "^IOL^IJ01000^IT01000\n"
X#define BITMAPSTART "^T00000^J00000^IP0202^P%04d\n"
X#define MINREPEAT 3
X#define MAXREPEAT 499 /* half of 999 */
X#define BITSON "^B%03d"
X#define BITSOFF "^D%03d"
X#define BITSOFFON "^C%03d%02X"
X#define DEFFORMAT "%02X"
X#define LO4MASK 0x0F
X#define HI4MASK 0xF0
X#define BITMAPEND "^G\n"
X#define NEWPAGE "^,\n"
//E*O*F printer.h//
echo x - Makefile
sed -e 's/^X//' > "Makefile" << '//E*O*F Makefile//'
X#
X# $Header: Makefile,v 1.6 86/07/19 16:53:52 gworek Exp $
X#
X# SUN screendump print filter for the QMS
X
XSRCS = screendump2qms.c
XOBJS = screendump2qms.o
XHDRS = printer.h
XDEST = screendump2qms
XINSTALLDIR = /usr/local/bin
X
XDFLAGS =
XCFLAGS = -O -s ${DFLAGS}
X
X${DEST}: ${OBJS}
X cc ${CFLAGS} -o ${DEST} ${OBJS}
X
X${OBJS}: ${HDRS}
X
Xinstall:
X install ${DEST} ${INSTALLDIR}
X
Xclean:
X /bin/rm -f *.o ${DEST}
X
Xlint: ${HDRS} ${SRCS}
X lint ${DFLAGS} ${SRCS}
//E*O*F Makefile//
exit 0
More information about the Comp.sources.unix
mailing list