[comp.text.tex] pbmtopk+pktopbm Part01/02

ajcd@cs.ed.ac.uk (Angus Duggan) (08/09/90)

Since there's been some interest in bitmap to pk font convertors, I thought
I'd post my attempt. pktopbm and pbmtopk were adapted from Tom Rokicki's C
versions of PKtoPX and PXtoPK on the TeX82 distribution tape, and are posted
without his permission. I expect that I've screwed up in the rounding code
somewhere, checking it will have to wait for a rainy day.

I haven't done anything about calculating the correct checksum for the font,
beyond extracting the appropriate (Pascal) code from pltotf.web and inserting
it as a comment.

Also, I would like a heuristic for calculating the x-height of the font, based
on the bitmap sizes, heights & depths etc.

THESE PROGRAMS COME WITHOUT ANY (IMPLIED OR OTHERWISE) WARRANTLY. I WILL NOT BE
HELD RESPONSIBLE FOR ANY DAMAGE TO YOUR DATA OR SYSTEM CAUSED BY USE OR MISUSE
OF THESE PROGRAMS. USE AT YOUR OWN RISK!

Suggestions, bug reports and fixes, etc, to ajcd@cs.ed.ac.uk, flames to
/dev/null.
==
Angus Duggan, Department of Computer Science,	| Ignorance of the manual is
University of Edinburgh, JCMB,			| no excuse.
The King's Buildings, Mayfield Road,		| JANET:  ajcd@uk.ac.ed.lfcs
Edinburgh, EH9 3JZ, Scotland.	| OR:  ajcd%lfcs.ed.ac.uk@nsfnet-relay.ac.uk

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then feed it
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix@uunet.uu.net if you want that tool.
# If this archive is complete, you will see the following message at the end:
#		"End of archive 1 (of 2)."
# Contents:  pbmtopk.1 pbmtopk.c pktopbm.1 pktopbm.c sign.pbm
# Wrapped by ajcd@harpo on Thu Aug  9 13:01:43 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'pbmtopk.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'pbmtopk.1'\"
else
echo shar: Extracting \"'pbmtopk.1'\" \(2944 characters\)
sed "s/^X//" >'pbmtopk.1' <<'END_OF_FILE'
X.TH pbmtopk 1 "6 August 1990"
X.SH NAME
Xpbmtopk - convert a portable bitmap into a packed (PK) format font
X.SH SYNOPSIS
Xpbmtopk pkfile[.pk] tfmfile[.tfm] resolution [-s designsize] [-p num param...]
X[-C codingscheme] [-F family] [-f optfile] [-c num]
X[-W width] [-H height] [-D depth]
X[-I ital] [-h horiz] [-v vert] [-x xoff] [-y yoff] [pbmfile]...
X.SH DESCRIPTION
XReads portable bitmaps as input, and produces a packed (PK) font file and a
XTFM (TeX font metric) file as output. The resolution parameter indicates the
Xresolution of the font, in dots per inch. If the filename "-" is used for any
Xof the filenames, the standard input stream (or standard output where
Xappropriate) will be used.
X.SH OPTIONS
X.IP "-s designsize"
XSets the design size of the font, in TeX's points (72.27pt to the inch). The
Xdefault design size is 1. The TFM parameters are given as multiples of the
Xdesign size.
X.IP "-p num param..."
XSets the first num font parameters for the font. The first seven parameters
Xare the slant,
Xinterword spacing, interword space stretchability, interword space
Xshrinkability, x-height, quad width, and post-sentence extra space of the
Xfont. Math and symbol fonts may have more parameters; see The TeXbook for a
Xlist of these. Reasonable default values are chosen for parameters which are
Xnot specified.
X.IP "-C codingscheme"
XSets the coding scheme comment in the TFM file.
X.IP "-F family"
XSets the font family comment in the TFM file.
X.IP "-f optfile"
XReads the file optfile, which should contain a lines of the form:
X.sp
X.nf
X.na
X   filename xoff yoff horiz vert width height depth ital
X.fi
X.ad
X.sp
XThe pbm files specified by the filename parameters are inserted consecutively
Xin the font with the specified attributes. If any of the attributes are
Xomitted, or replaced with "*", a default value will be calculated from the
Xsize of the bitmap. The settings of the -W, -H, -D, -I, -h, -v, -x, and -y
Xoptions do not affected characters created in this way. Lines beginning with
X"%" or "#" are ignored.
X.IP "-c num"
XSets the character number of the next bitmap encountered to num.
X.IP "-W width"
XSets the TFM width of the next character to width (in design size multiples).
X.IP "-H height"
XSets the TFM height of the next character to height (in design size multiples).
X.IP "-D depth"
XSets the TFM depth of the next character to depth (in design size multiples).
X.IP "-I ital"
XSets the italic correction of the next character to
Xital (in design size multiples).
X.IP "-h horiz"
XSets the horizontal escapement of the next character to horiz (in pixels).
X.IP "-v vert"
XSets the vertical escapement of the next character to vert (in pixels).
X.IP "-x xoff"
XSets the horizontal offset of the next character to xoff (in pixels).
X.IP "-y yoff"
XSets the vertical offset of the next character to yoff (in pixels, from the
Xtop row).
X.SH "SEE ALSO"
Xpktopbm(1), pbm(5)
X.SH AUTHOR
XAdapted from Tom Rokicki's pxtopk by Angus Duggan <ajcd@uk.ac.ed.lfcs>.

END_OF_FILE
echo shar: NEWLINE appended to \"'pbmtopk.1'\"
if test 2945 -ne `wc -c <'pbmtopk.1'`; then
    echo shar: \"'pbmtopk.1'\" unpacked with wrong size!
fi
# end of 'pbmtopk.1'
fi
if test -f 'pbmtopk.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'pbmtopk.c'\"
else
echo shar: Extracting \"'pbmtopk.c'\" \(24523 characters\)
sed "s/^X//" >'pbmtopk.c' <<'END_OF_FILE'
X/*
X  pbmtopk, adapted from "pxtopk.c by tomas rokicki" by AJCD 1/8/90
X  
X  compile with: cc -o pbmtopk pbmtopk.c -lm -lpbm
X  */
X
X#include <stdio.h>
X#include <pbm.h>
X#include <math.h>
X#include <ctype.h>
X
X#define MAXPKCHAR 256
X#define MAXOPTLINE 200
X#define MAXWIDTHTAB 256
X#define MAXHEIGHTTAB 16
X#define MAXDEPTHTAB 16
X#define MAXITALICTAB 64
X#define MAXPARAMS 30
X#define NAMELENGTH 80
X
X#define true (1)
X#define false (0)
X#define chr(a) a
X  
X#define round(a) ((int)(a+.5))
X#define fixword(d) ((int)aint((double)((d)*1048576)))
X#define unfixword(f) ((double)(f) / 1048576)
X#define fixrange(f) ((f) < 16777216 && (f) > -16777216)
X#define designunits(p) ((p)*72.27/(double)resolution/unfixword(designsize))
X
X/* character flags: in order of appearance in option files. */
X#define XOFFSET     1
X#define YOFFSET     2
X#define HORZESC     4
X#define VERTESC     8
X#define TFMWIDTH   16
X#define TFMHEIGHT  32
X#define TFMDEPTH   64
X#define TFMITALIC 128
X
Xtypedef int integer ;
Xtypedef char quarterword ;
Xtypedef char boolean ;
Xtypedef quarterword ASCIIcode ;
Xtypedef quarterword eightbits ;
Xtypedef FILE *bytefile ;
Xtypedef unsigned char byte ;
X
Xinteger resolution, designsize ;
Xchar *filename[MAXPKCHAR] ;
X
Xinteger xoffset[MAXPKCHAR] ;
Xinteger yoffset[MAXPKCHAR] ;
Xinteger horzesc[MAXPKCHAR] ;
Xinteger vertesc[MAXPKCHAR] ;
X
Xbyte tfmindex[MAXPKCHAR] ;
Xbyte hgtindex[MAXPKCHAR] ;
Xbyte depindex[MAXPKCHAR] ;
Xbyte italindex[MAXPKCHAR] ;
Xbyte charflags[MAXPKCHAR] ;
X
Xbit **bitmap ;
Xinteger smallestch, largestch ;
Xinteger emwidth ;
Xinteger checksum ;
Xchar *codingscheme = "GRAPHIC" ;
Xchar *familyname = "PBM" ;
X
Xinteger widthtab[MAXWIDTHTAB] ; /* TFM widths */
Xinteger numwidth ;      /* number of entries in width table */
Xinteger heighttab[MAXHEIGHTTAB] ;
Xinteger numheight ;
Xinteger depthtab[MAXDEPTHTAB] ;
Xinteger numdepth ;
Xinteger italictab[MAXITALICTAB] ;
Xinteger numitalic ;
Xinteger parameters[MAXPARAMS] ;
Xinteger numparam ;
X
XASCIIcode xord[128] ;
Xchar xchr[256] ;
Xbytefile tfmfile, pkfile ;
Xchar tfmname[NAMELENGTH+1], pkname[NAMELENGTH+1] ;
Xinteger pkloc ;
Xinteger bitweight ;
Xinteger outputbyte ;
Xinteger car ;
Xinteger hppp ;
Xinteger width ;
Xinteger height ;
Xinteger power[32] ;
X
Xinteger
Xcompute_checksum()
X{
X  /*
X    begin
X      c0:=bc; c1:=ec; c2:=bc; c3:=ec;
X      for c:=bc to ec do if char_wd[c]>0 then
X	begin
X	  temp_width:=memory[char_wd[c]];
X	  if design_units<>unity then
X	    temp_width:=round((temp_width/design_units)*1048576.0);
X	  temp_width:=temp_width + (c+4)*@'20000000; {this should be positive}
X	  c0:=(c0+c0+temp_width) mod 255;
X	  c1:=(c1+c1+temp_width) mod 253;
X	  c2:=(c2+c2+temp_width) mod 251;
X	  c3:=(c3+c3+temp_width) mod 247;
X	end;
X      header_bytes[check_sum_loc]:=c0;
X      header_bytes[check_sum_loc+1]:=c1;
X      header_bytes[check_sum_loc+2]:=c2;
X      header_bytes[check_sum_loc+3]:=c3;
X    end
X    */
X}
X
X#define add_tfmwidth(v) (add_tfmtable(widthtab, &numwidth, v, MAXWIDTHTAB,\
X				      "TFM width"))
X#define add_tfmheight(v) (add_tfmtable(heighttab, &numheight, v, MAXHEIGHTTAB,\
X				       "TFM height"))
X#define add_tfmdepth(v) (add_tfmtable(depthtab, &numdepth, v, MAXDEPTHTAB,\
X				      "TFM depth"))
X#define add_tfmitalic(v) (add_tfmtable(italictab, &numitalic, v, MAXITALICTAB,\
X				       "Italic correction"))
Xbyte
Xadd_tfmtable(table, count, value, max, name)
X     integer *table, *count, value, max;
X     char *name;
X{
X  integer i;
X  for (i = 0; i < *count; i++) /* search for value in tfm table */
X    if (table[i] == value) return (byte)i;
X  if (*count >= max) {
X    fprintf(stderr, "Too many values in %s table!\n", name) ;
X    jumpout();
X  }
X  if (!fixrange(value)) {
X    fprintf(stderr, " %s %f for char %d out of range!\n",
X	    name, unfixword(value), car);
X    jumpout();
X  }
X  table[*count] = value ;
X  return (*count)++ ;
X}
X
Xadd_suffix(name, suffix)
X     char *name, *suffix ;
X{
X  int haveext = 0;
X  if (name && strcmp(name, "-")) {
X    while (*name) {
X      if (*name == '/') haveext = 0 ;
X      else if (*name == '.') haveext = 1 ;
X      name++ ;
X    }
X    if (!haveext) {
X      *name++ = '.';
X      strcpy(name,suffix) ;
X    }
X  }
X}
X
Xinitialize()
X{
X  integer i ;
X  fprintf(stderr, "This is PBMtoPK, C Version 2.3\n") ;
X  for (i = 0 ; i <= 31 ; i ++) xchr[i] = '?' ;
X  xchr[32] = ' ' ;
X  xchr[33] = '!' ;
X  xchr[34] = '"' ;
X  xchr[35] = '#' ;
X  xchr[36] = '$' ;
X  xchr[37] = '%' ;
X  xchr[38] = '&' ;
X  xchr[39] = '\'' ;
X  xchr[40] = '(' ;
X  xchr[41] = ')' ;
X  xchr[42] = '*' ;
X  xchr[43] = '+' ;
X  xchr[44] = ',' ;
X  xchr[45] = '-' ;
X  xchr[46] = '.' ;
X  xchr[47] = '/' ;
X  xchr[48] = '0' ;
X  xchr[49] = '1' ;
X  xchr[50] = '2' ;
X  xchr[51] = '3' ;
X  xchr[52] = '4' ;
X  xchr[53] = '5' ;
X  xchr[54] = '6' ;
X  xchr[55] = '7' ;
X  xchr[56] = '8' ;
X  xchr[57] = '9' ;
X  xchr[58] = ':' ;
X  xchr[59] = ';' ;
X  xchr[60] = '<' ;
X  xchr[61] = '=' ;
X  xchr[62] = '>' ;
X  xchr[63] = '?' ;
X  xchr[64] = '@' ;
X  xchr[65] = 'A' ;
X  xchr[66] = 'B' ;
X  xchr[67] = 'C' ;
X  xchr[68] = 'D' ;
X  xchr[69] = 'E' ;
X  xchr[70] = 'F' ;
X  xchr[71] = 'G' ;
X  xchr[72] = 'H' ;
X  xchr[73] = 'I' ;
X  xchr[74] = 'J' ;
X  xchr[75] = 'K' ;
X  xchr[76] = 'L' ;
X  xchr[77] = 'M' ;
X  xchr[78] = 'N' ;
X  xchr[79] = 'O' ;
X  xchr[80] = 'P' ;
X  xchr[81] = 'Q' ;
X  xchr[82] = 'R' ;
X  xchr[83] = 'S' ;
X  xchr[84] = 'T' ;
X  xchr[85] = 'U' ;
X  xchr[86] = 'V' ;
X  xchr[87] = 'W' ;
X  xchr[88] = 'X' ;
X  xchr[89] = 'Y' ;
X  xchr[90] = 'Z' ;
X  xchr[91] = '[' ;
X  xchr[92] = '\\' ;
X  xchr[93] = ']' ;
X  xchr[94] = '^' ;
X  xchr[95] = '_' ;
X  xchr[96] = '`' ;
X  xchr[97] = 'a' ;
X  xchr[98] = 'b' ;
X  xchr[99] = 'c' ;
X  xchr[100] = 'd' ;
X  xchr[101] = 'e' ;
X  xchr[102] = 'f' ;
X  xchr[103] = 'g' ;
X  xchr[104] = 'h' ;
X  xchr[105] = 'i' ;
X  xchr[106] = 'j' ;
X  xchr[107] = 'k' ;
X  xchr[108] = 'l' ;
X  xchr[109] = 'm' ;
X  xchr[110] = 'n' ;
X  xchr[111] = 'o' ;
X  xchr[112] = 'p' ;
X  xchr[113] = 'q' ;
X  xchr[114] = 'r' ;
X  xchr[115] = 's' ;
X  xchr[116] = 't' ;
X  xchr[117] = 'u' ;
X  xchr[118] = 'v' ;
X  xchr[119] = 'w' ;
X  xchr[120] = 'x' ;
X  xchr[121] = 'y' ;
X  xchr[122] = 'z' ;
X  xchr[123] = '{' ;
X  xchr[124] = '|' ;
X  xchr[125] = '}' ;
X  xchr[126] = '~' ;
X  for (i = 127 ; i <= 255 ; i ++) xchr[i] = '?' ;
X  for (i = 0 ; i <= 127 ; i ++) xord[chr(i)] = 32 ;
X  for (i = 32 ; i <= 126 ; i ++) xord[xchr[i]] = i ;
X  for (i = 0 ; i < 32 ; i++) power[i] = 1 << i ;
X  for (i = 0; i < MAXPKCHAR; i++) {
X    filename[i] = NULL;
X    charflags[i] = 0;
X  }
X  pkloc = 0 ;
X  designsize = fixword(1.0) ;
X  numparam = 0;
X  widthtab[0] = heighttab[0] = depthtab[0] = italictab[0] = 0 ;
X  numwidth = numheight = numdepth = numitalic = 1;
X  smallestch = MAXPKCHAR ;
X  largestch = -1 ;
X  emwidth = 0 ;
X}
X
Xjumpout()
X{
X  exit(1) ;
X}
X
Xpkbyte(b)
X     integer b ;
X{
X  if (b < 0) b = b + 256 ;
X  putc(b, pkfile) ;
X  pkloc++ ;
X}
X
Xpkhalfword(a)
X     integer a ;
X{
X  if (a < 0) a = a + 65536 ;
X  pkbyte(a >> 8) ;
X  pkbyte(a & 255) ;
X}
X
Xpkthreebytes(a)
X     integer a ;
X{
X  pkbyte((a>>16) & 255) ;
X  pkbyte((a>>8) & 255) ;
X  pkbyte(a & 255) ;
X}
X
Xpkword(a)
X     integer a ;
X{
X  pkbyte((a>>24) & 255) ;
X  pkbyte((a>>16) & 255) ;
X  pkbyte((a>>8) & 255) ;
X  pkbyte(a & 255) ;
X}
X
Xpknyb(a)
X     integer a ;
X{
X  if (bitweight == 16) {
X    outputbyte = (a<<4) ;
X    bitweight = 1 ;
X  } else {
X    pkbyte(outputbyte + a) ;
X    bitweight = 16 ;
X  }
X}
X
Xwritepreamble()
X{
X  integer i ;
X  char *comment = "PBMtoPK 2.3 output" ;
X  
X  pkbyte(247) ;
X  pkbyte(89) ;
X  pkbyte(strlen(comment)) ;
X  for (i = 0 ; i < strlen(comment); i++) pkbyte(xord[comment[i]]) ;
X  pkword(designsize) ;
X  pkword(checksum) ; /* checksum; calculate if possible */
X  pkword(hppp) ;
X  pkword(hppp) ;
X}
X
Xwritepostamble()
X{
X  pkbyte(245) ;
X  while ((pkloc % 4 != 0)) pkbyte(246) ;
X  fprintf(stderr, "%d bytes written to packed file.\n", pkloc) ;
X}
X
Xtfmbyte(b)
X     integer b ;
X{
X  if (b < 0) b = b + 256 ;
X  putc(b, tfmfile) ;
X}
X
Xtfmhalfword(a)
X     integer a ;
X{
X  if (a < 0) a = a + 65536 ;
X  tfmbyte(a >> 8) ;
X  tfmbyte(a & 255) ;
X}
X
Xtfmword(a)
X     integer a ;
X{
X  tfmbyte((a>>24) & 255) ;
X  tfmbyte((a>>16) & 255) ;
X  tfmbyte((a>>8) & 255) ;
X  tfmbyte(a & 255) ;
X}
X
Xwritetfmfile()
X{
X  integer totallength ;
X  integer headersize = 17;
X  integer i ;
X
X  if (smallestch < 0 || largestch >= MAXPKCHAR) {
X    fprintf(stderr, " No characters read!\n") ;
X    jumpout() ;
X  }
X  if (numparam < 7) /* set default parameters */
X    switch (numparam) {
X    case 0: /* slant */
X      parameters[numparam++] = 0 ;
X    case 1: /* space */
X      parameters[numparam++] = fixword(designunits(emwidth/3.0));
X    case 2: /* space_stretch */
X      parameters[numparam++] = fixword(unfixword(parameters[1])/2.0) ;
X    case 3: /* space_shrink */
X      parameters[numparam++] = fixword(unfixword(parameters[1])/3.0) ;
X    case 4: /* x_height */
X      parameters[numparam++] = fixword(0.45);
X    case 5: /* quad */
X      parameters[numparam++] = fixword(designunits(emwidth)) ;
X    case 6: /* extra_space */
X      parameters[numparam++] = fixword(unfixword(parameters[1])/3.0) ;
X    }
X  totallength = 6 + headersize + (largestch+1-smallestch) +
X    numwidth + numheight + numdepth + numitalic + numparam ;
X  /* lengths */
X  tfmhalfword(totallength) ;
X  tfmhalfword(headersize) ;
X  tfmhalfword(smallestch) ;
X  tfmhalfword(largestch) ;
X  tfmhalfword(numwidth) ;
X  tfmhalfword(numheight) ;
X  tfmhalfword(numdepth) ;
X  tfmhalfword(numitalic) ;
X  tfmhalfword(0) ; /* lig/kern table */
X  tfmhalfword(0) ; /* kern table */
X  tfmhalfword(0) ; /* extensible char table */
X  tfmhalfword(numparam) ;
X  /* header */
X  tfmword(checksum) ;
X  tfmword(designsize) ;
X  if (strlen(codingscheme) > 39) tfmbyte(39) ;
X  else tfmbyte(strlen(codingscheme)) ;
X  for (i = 0; i < 39; i++)
X    if (*codingscheme) tfmbyte(xord[*codingscheme++]) ;
X    else tfmbyte(0) ;
X  if (strlen(familyname) > 19) tfmbyte(19) ;
X  else tfmbyte(strlen(familyname)) ;
X  for (i = 0; i < 19; i++)
X    if (*familyname) tfmbyte(xord[*familyname++]) ;
X    else tfmbyte(0) ;
X  /* char_info */
X  for (car = smallestch; car <= largestch; car++)
X    if (filename[car]) {
X      tfmbyte(tfmindex[car]) ;
X      tfmbyte((hgtindex[car]<<4) + depindex[car]) ;
X      tfmbyte(italindex[car]<<2) ;
X      tfmbyte(0) ;
X    } else tfmword(0) ;
X  /* width */
X  for (i = 0; i < numwidth; i++) tfmword(widthtab[i]) ;
X  /* height */
X  for (i = 0; i < numheight; i++) tfmword(heighttab[i]) ;
X  /* depth */
X  for (i = 0; i < numdepth; i++) tfmword(depthtab[i]) ;
X  /* italic */
X  for (i = 0; i < numitalic; i++) tfmword(italictab[i]) ;
X  /* no lig_kern, kern, or exten */
X  /* param */
X  for (i = 0; i < numparam; i++)
X    if (i && (!fixrange(parameters[i]))) {
X      fprintf(stderr, " Parameter %d out of range (-p)!\n", i);
X      jumpout();
X    }
X    else tfmword(parameters[i]) ;
X  fprintf(stderr, "%d bytes written to tfm file.\n", totallength*4) ;
X}
X
Xreadcharacter()
X{
X  FILE *fp;
X
X  if (!strcmp(filename[car], "-")) fp = stdin;
X  else if ((fp = fopen(filename[car], "r")) == NULL) {
X    fprintf(stderr, " Can't open pbm file %s!\n", filename[car]);
X    jumpout();
X  }
X  bitmap = pbm_readpbm(fp, &width, &height) ;
X  if (fp != stdin) fclose(fp) ;
X  
X  if ((charflags[car] & HORZESC) == 0) horzesc[car] = width ;
X  if ((charflags[car] & VERTESC) == 0) vertesc[car] = 0;
X  if ((charflags[car] & XOFFSET) == 0) xoffset[car] = 0;
X  if ((charflags[car] & YOFFSET) == 0) yoffset[car] = height-1;
X  if ((charflags[car] & TFMWIDTH) == 0)
X    tfmindex[car] = add_tfmwidth(fixword(designunits(width)));
X  if ((charflags[car] & TFMHEIGHT) == 0)
X    hgtindex[car] = add_tfmheight(fixword(designunits(yoffset[car]+1)));
X  if ((charflags[car] & TFMDEPTH) == 0)
X    depindex[car] = add_tfmdepth(fixword(designunits(height-1-yoffset[car])));
X  if ((charflags[car] & TFMITALIC) == 0) italindex[car] = 0;
X
X  if (car < smallestch) smallestch = car;
X  if (car > largestch) largestch = car;
X  if (width > emwidth) emwidth = width ;
X}
X
Xint
Xequal(row1, row2)
X     bit *row1, *row2 ;
X{
X  integer i ;
X  
X  for (i = 0; i < width; i++)
X    if (row1[i] != row2[i]) return (0) ;
X  return(1) ;
X}
X
Xshipcharacter()
X{
X  integer compsize ;
X  integer i, j, k ;
X  bit *zerorow, *onesrow ;
X  integer *repeatptr, *bitcounts ;
X  integer count ;
X  integer test ;
X  integer curptr, rowptr ;
X  integer bitval ;
X  integer repeatflag ;
X  integer colptr ;
X  integer currepeat ;
X  integer dynf ;
X  integer deriv[14] ;
X  integer bcompsize ;
X  boolean firston ;
X  integer flagbyte ;
X  boolean state ;
X  boolean on ;
X  integer hbit ;
X  integer pbit ;
X  boolean ron, son ;
X  integer rcount, scount ;
X  integer ri, si ;
X  integer max2 ;
X  integer predpkloc ;
X  integer buff ;
X
X  integer tfwid = widthtab[tfmindex[car]] ;
X  integer hesc = horzesc[car] ;
X  integer vesc = vertesc[car] ;
X  integer xoff = xoffset[car] ;
X  integer yoff = yoffset[car] ;
X
X  zerorow = pbm_allocrow(width) ;
X  onesrow = pbm_allocrow(width) ;
X  repeatptr =
X    (integer *)malloc((unsigned int)((height+1)*sizeof(integer))) ;
X  bitcounts =
X    (integer *)malloc((unsigned int)((height*width)*sizeof(integer))) ;
X  for (i = 0 ; i < width ; i++) {
X    zerorow[i] = PBM_WHITE ;
X    onesrow[i] = PBM_BLACK ;
X  }
X  for (i=0; i < height; i++) {
X    if (equal(bitmap[i], zerorow))
X      repeatptr[i] = 0 ;
X    else if (equal(bitmap[i], onesrow)) 
X      repeatptr[i] = 0 ;
X    else if (i + 1 < height && equal(bitmap[i],bitmap[i+1]))
X      repeatptr[i] = 1 ;
X    else
X      repeatptr[i] = 0 ;
X  }
X  i = 0 ;
X  while (i < height) {
X    k = i ;
X    while (repeatptr[k] == 1) k++ ;
X    repeatptr[i] = k - i ;
X    i = k + 1 ;
X  }
X  repeatptr[i] = 0 ;
X  colptr = width - 1 ;
X  repeatflag = currepeat = curptr = count = rowptr = 0 ;
X  test = PBM_WHITE ;
X  do {
X    colptr++ ;
X    if (colptr == width) {
X      colptr = 0 ;
X      rowptr = currepeat ;
X      if (repeatptr[currepeat] > 0) {
X	repeatflag = repeatptr[currepeat] ;
X	currepeat += repeatflag ;
X	rowptr += repeatflag ;
X      }
X      currepeat++ ;
X    }
X    if (rowptr >= height) bitval = -1 ;
X    else bitval = bitmap[rowptr][colptr] ;
X    if (bitval == test) count++ ;
X    else {
X      bitcounts[curptr++] = count ;
X      if (curptr+3 >= height*width) {
X	fprintf(stderr, " Out of memory while saving character counts!\n");
X	jumpout() ;
X      }
X      count = 1 ;
X      test = bitval ;
X      if (repeatflag > 0) {
X	bitcounts[curptr++] = -repeatflag ;
X	repeatflag = 0 ;
X      }
X    }
X  } while (test != -1) ;
X  bitcounts[curptr] = 0 ;
X  bitcounts[curptr + 1] = 0 ;
X  for (i = 1 ; i <= 13 ; i ++) deriv[i] = 0 ;
X  i = firston = (bitcounts[0] == 0) ;
X  compsize = 0 ;
X  while (bitcounts[i] != 0) {
X    j = bitcounts[i] ;
X    if (j == -1) compsize++ ;
X    else {
X      if (j < 0) {
X	compsize++ ;
X	j = -j ;
X      }
X      if (j < 209) compsize += 2 ;
X      else {
X	k = j - 193 ;
X	while (k >= 16) {
X	  k >>= 4 ;
X	  compsize += 2 ;
X	}
X	compsize++ ;
X      }
X      if (j < 14) (deriv[j])-- ;
X      else if (j < 209) (deriv[(223 - j) / 15])++ ;
X      else {
X	k = 16 ;
X	while (((k<<4) < j + 3)) k <<= 4 ;
X	if (j - k <= 192)
X	  deriv[(207 - j + k) / 15] += 2 ;
X      }
X    }
X    i++ ;
X  }
X  bcompsize = compsize ;
X  dynf = 0 ;
X  for (i = 1 ; i <= 13 ; i ++) {
X    compsize += deriv[i] ;
X    if (compsize <= bcompsize) {
X      bcompsize = compsize ;
X      dynf = i ;
X    }
X  }
X  compsize = ((bcompsize + 1)>>1) ;
X  if ((compsize > ((height*width+7)>>3)) || (height*width == 0)) {
X    compsize = ((height*width+7)>>3) ;
X    dynf = 14 ;
X  }
X  flagbyte = (dynf<<4) ;
X  if (firston) flagbyte |= 8 ;
X  if ((tfwid > 16777215) || (tfwid < 0) || (hesc < 0) || (vesc != 0) ||
X      (compsize > 196579) || (width > 65535) || (height > 65535) ||
X      (xoff > 32767) || (yoff > 32767) || (xoff < -32768) || (yoff < -32768)) {
X    flagbyte |= 7 ;
X    pkbyte(flagbyte) ;
X    compsize += 28 ;
X    pkword(compsize) ;
X    pkword(car) ;
X    predpkloc = pkloc + compsize ;
X    pkword(tfwid) ;
X    pkword(hesc<<16) ;
X    pkword(vesc<<16) ;
X    pkword(width) ;
X    pkword(height) ;
X    pkword(xoff) ;
X    pkword(yoff) ;
X  } else if ((hesc > 255) || (width > 255) || (height > 255) ||
X	   (xoff > 127) || (yoff > 127) || (xoff < -128) ||
X	   (yoff < -128) || (compsize > 1016)) {
X    compsize += 13 ;
X    flagbyte += (compsize>>16) + 4 ;
X    pkbyte(flagbyte) ;
X    pkhalfword(compsize & 65535) ;
X    pkbyte(car) ;
X    predpkloc = pkloc + compsize ;
X    pkthreebytes(tfwid) ;
X    pkhalfword(hesc) ;
X    pkhalfword(width) ;
X    pkhalfword(height) ;
X    pkhalfword(xoff) ;
X    pkhalfword(yoff) ;
X  } else {
X    compsize += 8 ;
X    flagbyte = flagbyte + (compsize>>8) ;
X    pkbyte(flagbyte) ;
X    pkbyte(compsize & 255) ;
X    pkbyte(car) ;
X    predpkloc = pkloc + compsize ;
X    pkthreebytes(tfwid) ;
X    pkbyte(hesc) ;
X    pkbyte(width) ;
X    pkbyte(height) ;
X    pkbyte(xoff) ;
X    pkbyte(yoff) ;
X  }
X  if (dynf != 14) {
X    bitweight = 16 ;
X    max2 = 208 - 15 * dynf ;
X    i = firston ;
X    while (bitcounts[i] != 0) {
X      j = bitcounts[i] ;
X      if (j == - 1) pknyb(15) ;
X      else {
X	if (j < 0) {
X	  pknyb(14) ;
X	  j = -j ;
X	}
X	if (j <= dynf) pknyb(j) ;
X	else if (j <= max2) {
X	  j -= dynf + 1 ;
X	  pknyb((j >> 4) + dynf + 1) ;
X	  pknyb((j & 15)) ;
X	} else {
X	  j -= max2 - 15 ;
X	  k = 16 ;
X	  while (k <= j) {
X	    k <<= 4 ;
X	    pknyb(0) ;
X	  }
X	  while (k > 1) {
X	    k >>= 4 ;
X	    pknyb(j / k) ;
X	    j = j % k ;
X	  }
X	}
X      }
X      i++ ;
X    }
X    if (bitweight != 16) pkbyte(outputbyte) ;
X  } else {
X    buff = 0 ;
X    pbit = 8 ;
X    i = firston ;
X    hbit = width ;
X    on = ! firston ;
X    state = false ;
X    count = repeatflag = 0 ;
X    while ((bitcounts[i] != 0) || state || (count > 0)) {
X      if (state) {
X	count = rcount ;
X	i = ri ;
X	on = ron ;
X	repeatflag-- ;
X      } else {
X	rcount = count ;
X	ri = i ;
X	ron = on ;
X      }
X      do {
X	if (count == 0) {
X	  if (bitcounts[i] < 0) {
X	    if (! state) repeatflag = -bitcounts[i] ;
X	    i++ ;
X	  }
X	  count = bitcounts[i] ;
X	  i++ ;
X	  on = !on ;
X	}
X	if ((count >= pbit) && (pbit < hbit)) {
X	  if (on) buff += power[pbit] - 1 ;
X	  pkbyte(buff) ;
X	  buff = 0 ;
X	  hbit -= pbit ;
X	  count -= pbit ;
X	  pbit = 8 ;
X	} else if ((count < pbit) && (count < hbit)) {
X	  if (on) buff += power[pbit] - power[pbit - count] ;
X	  pbit -=  count ;
X	  hbit -= count ;
X	  count = 0 ;
X	} else {
X	  if (on) buff += power[pbit] - power[pbit - hbit] ;
X	  count -= hbit ;
X	  pbit -= hbit ;
X	  hbit = width ;
X	  if (pbit == 0) {
X	    pkbyte(buff) ;
X	    buff = 0 ;
X	    pbit = 8 ;
X	  }
X	}
X      } while (hbit != width) ;
X      if (state && (repeatflag == 0)) {
X	count = scount ;
X	i = si ;
X	on = son ;
X	state = false ;
X      } else if (! state && (repeatflag > 0)) {
X	scount = count ;
X	si = i ;
X	son = on ;
X	state = true ;
X      }
X    }
X    if (pbit != 8) pkbyte(buff) ;
X  }
X  if (predpkloc != pkloc) {
X    fprintf(stderr, " Bad predicted character length: character %d!\n", car);
X    jumpout() ;
X  }
X  pbm_freerow(zerorow); 
X  pbm_freerow(onesrow); 
X  free((char *)repeatptr);
X  free((char *)bitcounts);
X}
X
Xusage()
X{
X  fprintf(stderr, " Usage: pbmtopk pkfile[.pk] tfmfile[.tfm] dpi\n") ;
X  fprintf(stderr, "                [-s designsize] [-p num param...]\n");
X  fprintf(stderr, "                [-C codingscheme ] [-F family]\n");
X  fprintf(stderr, "                [-c num | <char>]...\n");
X  fprintf(stderr, " <char> is:     [-W tfmwidth] [-H tfmheight] [-D tfmdepth]\n");
X  fprintf(stderr, "                [-I ital_corr] [-h horiz] [-v vert]\n") ;
X  fprintf(stderr, "                [-x xoffset] [-y yoffset] file\n") ;
X  fprintf(stderr, " or:            -f optfile\n") ;
X  jumpout() ;
X}
X
Xcheckchar()
X{
X  if (car < 0 || car >= MAXPKCHAR) {
X    fprintf(stderr, " Character must be in range 0 to %d (-c)!\n",
X	    MAXPKCHAR-1) ;
X    jumpout() ;
X  }
X}
X
Xoptionfile(name)
X     char *name ;
X{
X  FILE *fp ;
X  char buffer[MAXOPTLINE] ;
X  
X  if (!strcmp(name, "-")) fp = stdin ;
X  else if ((fp = fopen(name, "r")) == NULL) {
X    fprintf(stderr, " Can't open option file %s!\n", name) ;
X    jumpout() ;
X  }
X  while (!feof(fp)) {
X    char *here = buffer;
X
X    if (fgets(buffer, MAXOPTLINE, fp) == NULL) break ;
X    while (isspace(*here)) here++ ;
X    if (*here && *here != '%' && *here != '#') {
X      char str[NAMELENGTH] ;
X      integer i, n;
X      
X      checkchar() ;
X      if (sscanf(here, "%s%n", str, &n) != 1) {
X	fprintf(stderr, "Bad option file line %s!\n", buffer) ;
X	jumpout() ;
X      }
X      filename[car] =
X	(char *)malloc((unsigned int)(sizeof(char)*(strlen(str)+1))) ;
X      strcpy(filename[car], str) ;
X      for (i = 1; i < 256; i<<=1) {
X	here += n;
X	if (sscanf(here, "%s%n", str, &n) != 1) break ;
X	if (strcmp(str, "*")) {
X	  charflags[car] |= i ;
X	  switch (i) {
X	  case XOFFSET:
X	    xoffset[car] = atoi(str) ;
X	    break ;
X	  case YOFFSET:
X	    yoffset[car] = atoi(str) ;
X	    break ;
X	  case HORZESC:
X	    horzesc[car] = atoi(str) ;
X	    break ;
X	  case VERTESC:
X	    vertesc[car] = atoi(str) ;
X	    break ;
X	  case TFMWIDTH:
X	    tfmindex[car] = add_tfmwidth(fixword(atof(str))) ;
X	    break ;
X	  case TFMHEIGHT:
X	    hgtindex[car] = add_tfmheight(fixword(atof(str))) ;
X	    break ;
X	  case TFMDEPTH:
X	    depindex[car] = add_tfmdepth(fixword(atof(str))) ;
X	    break ;
X	  case TFMITALIC:
X	    italindex[car] = add_tfmitalic(fixword(atof(str))) ;
X	    break ;
X	  }
X	}
X      }
X      car++ ;
X    }
X  }
X  if (fp != stdin) fclose(fp) ;
X}
X
Xdialog(gargc, gargv)
X     int gargc ;
X     char **gargv ;
X{
X  integer i, hesc, vesc, xoff, yoff, tfwid, tfdep, tfhgt, tfital ;
X  byte flags ;
X  
X  if (--gargc < 1) usage() ;
X  strcpy(pkname, *++gargv) ;
X  add_suffix(pkname, "pk") ;
X  
X  if (--gargc < 1) usage() ;
X  strcpy(tfmname, *++gargv) ;
X  add_suffix(tfmname, "tfm") ;
X  
X  if (--gargc < 1) usage() ;
X  resolution = atoi(*++gargv) ;
X  if (resolution < 1 || resolution > 32767) {
X    fprintf(stderr, " Unlikely resolution %d dpi!\n", resolution);
X    jumpout();
X  }
X  
X  car = flags = hesc = vesc = xoff = yoff = tfwid = 0;
X  while (++gargv, --gargc) {
X    if (gargv[0][0] == '-' && gargv[0][1]) {
X      char c, *p;
X      c = gargv[0][1] ;
X      if (gargv[0][2]) p = *gargv + 2 ;
X      else if (++gargv, --gargc) p = *gargv ;
X      else usage() ;
X      switch (c) {
X      case 'C':
X	codingscheme = p;
X	break ;
X      case 'F':
X	familyname = p;
X	break ;
X      case 'c':
X	car = atoi(p) ;
X	break ;
X      case 's':
X	designsize = fixword(atof(p));
X	if (designsize < 1048576) {
X	  fprintf(stderr, " Design size %f out of range!\n",
X		  unfixword(designsize));
X	  jumpout() ;
X	}
X      case 'h':
X	hesc = atoi(p) ;
X	flags |= HORZESC ;
X	break ;
X      case 'v':
X	vesc = atoi(p) ;
X	flags |= VERTESC ;
X	break ;
X      case 'x':
X	xoff = atoi(p) ;
X	flags |= XOFFSET ;
X	break ;
X      case 'y':
X	yoff = atoi(p) ;
X	flags |= YOFFSET ;
X	break ;
X      case 'W':
X	tfwid = fixword(atof(p)) ;
X	flags |= TFMWIDTH ;
X	break ;
X      case 'H':
X	tfhgt = fixword(atof(p)) ;
X	flags |= TFMHEIGHT ;
X	break ;
X      case 'D':
X	tfdep = fixword(atof(p)) ;
X	flags |= TFMDEPTH ;
X	break ;
X      case 'I':
X	tfital = fixword(atof(p)) ;
X	flags |= TFMITALIC ;
X	break ;
X      case 'f':
X	optionfile(p) ;
X	break ;
X      case 'p':
X	numparam = atoi(p);
X	if (numparam < 1 || numparam > 30) {
X	  fprintf(stderr, " Parameter count %d out of range!\n", numparam);
X	  jumpout();
X	}
X	for (i=0; i<numparam; i++)
X	  if (++gargv,--gargc) parameters[i] = fixword(atof(*gargv)) ;
X	  else {
X	    fprintf(stderr, " Not enough parameters (-p)!\n");
X	    jumpout() ;
X	  }
X	break ;
X      default:
X	usage() ;
X      }
X    } else  {
X      checkchar() ;
X      if (flags & TFMWIDTH)
X	tfmindex[car] = add_tfmwidth(tfwid);
X      if (flags & TFMDEPTH)
X	depindex[car] = add_tfmdepth(tfdep);
X      if (flags & TFMHEIGHT)
X	hgtindex[car] = add_tfmheight(tfhgt);
X      if (flags & TFMITALIC)
X	italindex[car] = add_tfmitalic(tfital);
X      horzesc[car] = hesc ;
X      vertesc[car] = vesc ;
X      xoffset[car] = xoff ;
X      yoffset[car] = yoff ;
X      filename[car] = *gargv ;
X      charflags[car] = flags ;
X      car++ ;
X      flags = 0;
X    }
X  }
X}
X
Xmain(argc, argv)
X     int argc ;
X     char *argv[] ;
X{
X  initialize() ;
X  dialog(argc, argv) ;
X  hppp = round((resolution<<16) / 72.27) ;
X  add_suffix(pkname, "pk") ;
X  add_suffix(tfmname, "tfm") ;
X  if (!strcmp(pkname, "-")) pkfile = stdout;
X  else if ((pkfile = fopen(pkname, "w")) == NULL) {
X    fprintf(stderr, " Can't open PK file %s!\n", pkname);
X    jumpout() ;
X  }
X  if (!strcmp(tfmname, "-")) tfmfile = stdout ;
X  else if ((tfmfile = fopen(tfmname, "w")) == NULL) {
X    fprintf(stderr, " Can't open TFM file %s!\n", tfmname);
X    jumpout();
X  }
X  writepreamble() ;
X  for (car = 0 ; car < MAXPKCHAR ; car++)
X    if (filename[car]) {
X      readcharacter() ;
X      shipcharacter() ;
X    }
X  writepostamble() ;
X  writetfmfile() ;
X  if (pkfile != stdout) fclose(pkfile) ;
X  if (tfmfile != stdout) fclose(tfmfile) ;
X}

END_OF_FILE
echo shar: NEWLINE appended to \"'pbmtopk.c'\"
if test 24524 -ne `wc -c <'pbmtopk.c'`; then
    echo shar: \"'pbmtopk.c'\" unpacked with wrong size!
fi
# end of 'pbmtopk.c'
fi
if test -f 'pktopbm.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'pktopbm.1'\"
else
echo shar: Extracting \"'pktopbm.1'\" \(592 characters\)
sed "s/^X//" >'pktopbm.1' <<'END_OF_FILE'
X.TH pktopbm 1 "6 August 1990"
X.SH NAME
Xpktopbm - convert packed (PK) format font into portable bitmap(s)
X.SH SYNOPSIS
Xpktopbm pkfile[.pk] [-c num] pbmfile ...
X.SH DESCRIPTION
XReads a packed (PK) font file as input, and produces portable bitmaps as
Xoutput. If the filename "-" is used for any
Xof the filenames, the standard input stream (or standard output where
Xappropriate) will be used.
X.SH OPTIONS
X.IP "-c num"
XSets the character number of the next bitmap written to num.
X.SH "SEE ALSO"
Xpbmtopk(1), pbm(5)
X.SH AUTHOR
XAdapted from Tom Rokicki's pxtopk by Angus Duggan <ajcd@uk.ac.ed.lfcs>.

END_OF_FILE
echo shar: NEWLINE appended to \"'pktopbm.1'\"
if test 593 -ne `wc -c <'pktopbm.1'`; then
    echo shar: \"'pktopbm.1'\" unpacked with wrong size!
fi
# end of 'pktopbm.1'
fi
if test -f 'pktopbm.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'pktopbm.c'\"
else
echo shar: Extracting \"'pktopbm.c'\" \(8311 characters\)
sed "s/^X//" >'pktopbm.c' <<'END_OF_FILE'
X/*
X  pktopbm, adapted from "pktopx in C by Tomas Rokicki" by AJCD 1/8/90
X  
X  compile with: cc -lpbm -o pktopbm pktopbm.c
X  */
X
X#include <stdio.h>
X#include <pbm.h>
X
X#define NAMELENGTH 80
X#define MAXROWWIDTH 3200
X#define MAXPKCHAR 256
X
X#define round(a) ((int)(a+0.5))
X
Xtypedef int integer ;
Xtypedef unsigned char quarterword ;
Xtypedef char boolean ;
Xtypedef quarterword eightbits ;
Xtypedef FILE *bytefile ;
X
Xbytefile pkfile ;
Xchar pkname[NAMELENGTH+1] ;
Xinteger pkloc ;
Xinteger i, j ;
Xchar *filename[MAXPKCHAR] ;
Xbit **bitmap = NULL ;
Xinteger dynf ;
Xeightbits inputbyte ;
Xeightbits bitweight ;
Xinteger repeatcount ;
Xinteger flagbyte ;
X
Xadd_suffix(name, suffix)
X     char *name, *suffix ;
X{
X  int haveext = 0;
X  if (name) {
X    while (*name) {
X      if (*name == '/') haveext = 0 ;
X      else if (*name == '.') haveext = 1 ;
X      name++ ;
X    }
X    if (!haveext) {
X      *name++ = '.';
X      strcpy(name,suffix) ;
X    }
X  }
X}
X
Xinitialize()
X{
X  integer i ;
X  
X  fprintf(stderr, "This is PKtoPBM, C Version 2.3\n") ;
X  for (i = 0 ; i < MAXPKCHAR ; i ++) filename[i] = NULL ;
X}
X
Xjumpout()
X{
X  exit(1) ;
X}
X
Xopenpkfile()
X{
X  if ((pkfile = fopen(pkname, "r")) == NULL) {
X    fprintf(stderr, " Can't open pk file %s!\n", pkname) ;
X  }
X  pkloc = 0 ;
X}
X
Xeightbits pkbyte()
X{
X  pkloc++ ;
X  return(getc(pkfile)) ;
X}
X
Xinteger get16()
X{
X  integer a = pkbyte() ;
X  return((a<<8) + pkbyte()) ;
X}
X
Xinteger get32()
X{
X  integer a = get16() ;
X  if (a > 32767) a -= 65536 ;
X  return((a<<16) + get16()) ;
X}
X
Xinteger getnyb()
X{
X  eightbits temp ;
X  if (bitweight == 0) {
X    inputbyte = pkbyte() ;
X    bitweight = 16 ;
X  }
X  temp = inputbyte / bitweight ;
X  inputbyte -= temp * bitweight ;
X  bitweight >>= 4 ;
X  return(temp) ;
X}
X
Xboolean getbit()
X{
X  boolean temp ;
X  bitweight >>= 1 ;
X  if (bitweight == 0) {
X    inputbyte = pkbyte() ;
X    bitweight = 128 ;
X  }
X  temp = (inputbyte >= bitweight) ;
X  if (temp) inputbyte -= bitweight ;
X  return(temp) ;
X}
X
Xinteger pkpackednum()
X{
X  integer i, j, k ;
X  i = getnyb() ;
X  if (i == 0) {
X    do {
X      j = getnyb() ;
X      i++ ;
X    } while (!(j != 0)) ;
X    while (i > 0) {
X      j = (j<<4) + getnyb() ;
X      i-- ;
X    }
X    return(j - 15 +((13 - dynf)<<4) + dynf) ;
X  } else if (i <= dynf) return(i) ;
X  else if (i < 14) return(((i - dynf - 1)<<4) + getnyb() + dynf + 1) ;
X  else {
X    if (i == 14) repeatcount = pkpackednum() ;
X    else repeatcount = 1 ;
X    return(pkpackednum()) ;
X  }
X}
X
Xskipspecials()
X{
X  integer i, j, k ;
X  do {
X    flagbyte = pkbyte() ;
X    if (flagbyte >= 240)
X      switch(flagbyte) {
X      case 240:
X      case 241:
X      case 242:
X      case 243:
X	i = 0 ;
X	for (j = 240 ; j <= flagbyte ; j ++) i = (i<<8) + pkbyte() ;
X	for (j = 1 ; j <= i ; j ++) k = pkbyte() ;
X	break ;
X      case 244:
X	i = get32() ;
X	break ;
X      case 245:
X	break ;
X      case 246:
X	break ;
X      case 247:
X      case 248:
X      case 249:
X      case 250:
X      case 251:
X      case 252:
X      case 253:
X      case 254:
X      case 255:
X	fprintf(stderr, " Unexpected flag byte %d!\n", flagbyte) ;
X	jumpout() ;
X      }
X  } while (!((flagbyte < 240) || (flagbyte == 245))) ;
X}
X
Xusage()
X{
X  fprintf(stderr, " Usage: pktopbm pkfile[.pk] [[-c num] pbmfile]...\n");
X  jumpout() ;
X}
X
Xdialog(gargc, gargv)
X     int gargc ;
X     char **gargv ;
X{
X  integer car ;
X  
X  if (--gargc < 1) usage() ;
X  strcpy(pkname, *++gargv) ;
X  add_suffix(pkname, "pk") ;
X  car = 0 ;
X  while (++gargv, --gargc) {
X    if (gargv[0][0] == '-' && gargv[0][1])
X      switch (gargv[0][1]) {
X      case 'c':
X	if (gargv[0][2]) car = atoi(*gargv+2) ;
X	else if (++gargv, --gargc) car = atoi(*gargv) ;
X	else usage() ;
X	break ;
X      default:
X	usage() ;
X      } else if (car < 0 || car >= MAXPKCHAR) {
X	fprintf(stderr, " Character must be in range 0 to %d (-c)!\n",
X		MAXPKCHAR-1) ;
X	jumpout() ;
X      } else filename[car++] = *gargv ;
X  }
X}
X
Xmain(argc, argv)
X     int argc ;
X     char *argv[] ;
X{
X  integer endofpacket ;
X  integer designsize ;
X  integer checksum ;
X  integer hppp, vppp ;
X  integer cheight, cwidth ;
X  integer horesc ;
X  integer packetlength ;
X  integer rowsleft ;
X  boolean turnon ;
X  integer hbit ;
X  integer count ;
X  integer rp ;
X  integer i, j, k ;
X  integer car ;
X  bit row[MAXROWWIDTH+1] ;
X  
X  initialize() ;
X  dialog(argc, argv) ;
X  openpkfile() ;
X  if (pkbyte() != 247) {
X    fprintf(stderr, " Bad pk file (pre command missing)!\n") ;
X    jumpout() ;
X  }
X  if (pkbyte() != 89) {
X    fprintf(stderr, " Wrong version of packed file!\n") ;
X    jumpout() ;
X  }
X  j = pkbyte() ;
X  for (i = 1 ; i <= j ; i ++) k = pkbyte() ;
X  designsize = get32() ;
X  checksum = get32() ;
X  hppp = get32() ;
X  vppp = get32() ;
X  if (hppp != vppp) fprintf(stderr, " Warning: aspect ratio not 1:1!\n") ;
X  skipspecials() ;
X  while (flagbyte != 245) {
X    dynf = (flagbyte>>4) ;
X    flagbyte &= 15 ;
X    turnon = (flagbyte >= 8) ;
X    if (turnon) flagbyte &= 7 ;
X    if (flagbyte == 7) {
X      packetlength = get32() ;
X      car = get32() ;
X      endofpacket = packetlength + pkloc ;
X      if ((car >= MAXPKCHAR) || (car < 0)) goto lab9997 ;
X      i = get32() ; /* tfmwidth */
X      horesc = get32() ;
X      i = get32() ;
X      cwidth = get32() ;
X      cheight = get32() ;
X      if ((cwidth < 0) || (cheight < 0) || (cwidth > 65535) || (cheight > 65535)) goto lab9997 ;
X      i = get32() ;
X      j = get32() ;
X    } else if (flagbyte > 3) {
X      packetlength =((flagbyte - 4)<<16) + get16() ;
X      car = pkbyte() ;
X      endofpacket = packetlength + pkloc ;
X      if (car >= MAXPKCHAR) goto lab9997 ;
X      i = pkbyte() ; /* tfmwidth */
X      i = get16() ;
X      horesc = get16() ;
X      cwidth = get16() ;
X      cheight = get16() ;
X      i = get16() ;
X      j = get16() ;
X    } else {
X      packetlength = (flagbyte<<8) + pkbyte() ;
X      car = pkbyte() ;
X      endofpacket = packetlength + pkloc ;
X      if (car >= MAXPKCHAR) goto lab9997 ;
X      i = pkbyte() ; /* tfmwidth */
X      i = get16() ;
X      horesc = pkbyte() ;
X      cwidth = pkbyte() ;
X      cheight = pkbyte() ;
X      i = pkbyte() ;
X      j = pkbyte() ;
X    }
X    if (filename[car]) {
X      bitmap = pbm_allocarray(cwidth, cheight) ;
X      if (bitmap == NULL) {
X	fprintf(stderr, " Out of memory allocating bitmap!\n") ;
X	jumpout() ;
X      }
X    } else goto lab9997 ;
X    bitweight = 0 ;
X    if (dynf == 14) {
X      for (i = 1 ; i <= cheight ; i ++)
X	for (j = 1 ; j <= cwidth ; j ++) {
X	  if (getbit())
X	    bitmap[i][j] = PBM_BLACK ;
X	  else
X	    bitmap[i][j] = PBM_WHITE ;
X	}
X    } else {
X      rowsleft = cheight ;
X      hbit = cwidth ;
X      repeatcount = rp =0 ;
X      while (rowsleft > 0) {
X	count = pkpackednum() ;
X	while (count > 0) {
X	  if (count < hbit) {
X	    hbit -= count ;
X	    while (count--) {
X	      if (turnon)
X		row[rp++] = PBM_BLACK ;
X	      else
X		row[rp++] = PBM_WHITE ;
X	    }
X	  } else {
X	    count -= hbit ;
X	    while (hbit--) {
X	      if (turnon)
X		row[rp++] = PBM_BLACK ;
X	      else
X		row[rp++] = PBM_WHITE ;
X	    }
X	    for (i = 0; i <= repeatcount; i++)
X	      for (j = 0; j < cwidth; j++)
X		bitmap[i + cheight-rowsleft][j] = row[j] ;
X	    rowsleft -= repeatcount + 1;
X	    repeatcount = rp = 0 ;
X	    hbit = cwidth ;
X	  }
X	}
X	turnon = ! turnon ;
X      }
X      if ((rowsleft != 0) || (hbit != cwidth)) {
X	fprintf(stderr, " Bad pk file (more bits than required)!\n") ;
X	jumpout() ;
X      }
X    }
X    if (endofpacket != pkloc) {
X      fprintf(stderr, " Bad pk file (bad packet length)!\n") ;
X      jumpout() ;
X    }
X    /* output bitmap to file */
X    {
X      FILE *fp ;
X      if (!strcmp(filename[car], "-"))
X	fp = stdout ;
X      else {
X	if ((fp = fopen(filename[car], "w")) == NULL) {
X	  fprintf(stderr, " Can't open file %s!\n", filename[car]) ;
X	  jumpout() ;
X	}
X      }
X      filename[car] = NULL;
X      pbm_writepbm(fp, bitmap, cwidth, cheight) ;
X      pbm_freearray(bitmap, cheight) ;
X      if (fp != stdout) (void)fclose(fp) ;
X    }
X    goto lab9998 ;
X  lab9997: while (pkloc != endofpacket) i = pkbyte() ;
X    if (car < 0 || car >= MAXPKCHAR)
X      fprintf(stderr, " Character %d out of range!\n", car) ;
X  lab9998: skipspecials() ;
X  }
X  while (! feof(pkfile)) i = pkbyte() ;
X  pkloc-- ;
X  for (car = 0; car < MAXPKCHAR; car++)
X    if (filename[car])
X      fprintf(stderr, " Warning: No character in position %d (file %s).\n",
X	      car, filename[car]) ;
X  fprintf(stderr, "%d bytes read from packed file.\n", pkloc) ;
X}

END_OF_FILE
echo shar: NEWLINE appended to \"'pktopbm.c'\"
if test 8312 -ne `wc -c <'pktopbm.c'`; then
    echo shar: \"'pktopbm.c'\" unpacked with wrong size!
fi
# end of 'pktopbm.c'
fi
if test -f 'sign.pbm' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sign.pbm'\"
else
echo shar: Extracting \"'sign.pbm'\" \(15311 characters\)
sed "s/^X//" >'sign.pbm' <<'END_OF_FILE'
XP1
X150 100
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000001111110000000000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000111111111000000000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000011110000011100000000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000001111000000000110000000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000011100000000000011000000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000011000000000000001100000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000110000000000000001100000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000001100000000000000000110000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000011000000000000000000110000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000011000000000000000000110000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000110000000000000000000011000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000110000000000000000000011000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000001100000000000000000000011000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000001100000000000000000000001100000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000011000000000000000000000001100000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000011000000000000000000000001100000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000110000000000000000000000001100000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000110000000000000000000000001100000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000001100000000000000000000000011000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000001100000000000000000000000011000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000001100000000000000000000000011000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000011000000000000000000000000011000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000011000000000000000000000000011000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000011000000000000000000000000011000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000110000000000000000000000000011000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000110000000000000000000000000011000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000001100000000000000000000000000110000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000001100000000000000000000000000110000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000001100000000000000000000000000110000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000011000000000000000000000000000110011000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000011000000000000000000000000000110011000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000011000000000000000000000000001100110000011000000111111100000000
X0000000111100000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000011000000000000000000000000001100110000011000011111111110000000
X0000011111111000000000000000000000000000000000000000011110000000000000
X0000000000
X0000000011000000000000000000000000001101110000011000111100000111000000
X0001110000011100000000000000000011000000000000000001111111000000000000
X0000000000
X0000000110000000000000000000000000011001100000111001110000000011100000
X0011100000001100000000000000000111100000000000000001100001000000000000
X0000000000
X0000000110000000000000000000000000011011100001101011000000000001110000
X0011000000000110000100000000001101100000000000000011000011000000000000
X0000000000
X0000000110000000000000000000000000011111100001101011000000000000110000
X0110000000000110000100000000001101100000000000000011000110000000000000
X0000000000
X0000000110000000000000000000000000000111000011001110000000000000110000
X0100000000000010001100000000011001100000000000000011111100000000000000
X0000000000
X0000000110000000000000000000000000001111000011001100000000000000110000
X1100000000000011001100000000011001100000000000000000111111000000000000
X0000000000
X0000000110000000000000000000000000001111000010001100000000000000110000
X1000000000000011001100000000111011000000000000000001110011110000000000
X0000000000
X0000000110000000000000000000000000011110000110011100000000000000110001
X1000000000000011001100000000110011000000000000000001100000111000000000
X0000000000
X0000000110000000000000000000000000110110000110011000000000000001100001
X1000000000000011011100000000110011000000000000000011000000001110000000
X0000000000
X0000000110000000000000000000000001101100000100011000000000000001100001
X1000000000000011011100000000110110000000000000000110000000000111000000
X0000000000
X0000000110000000000000000000000001101100001100111000000000000001100001
X1000000000000001011100000000111110000000000000001100000000000011000000
X0000000000
X0000000110000000000000000000000011001100001000111000000000000001100001
X1000000000000000111100000000111100000000000000011000000000000001100000
X0000000000
X0000000110000000000000000000000011001000011000110000000000000011000001
X1000000000000000111100000000111000000000000000110000000000000001100000
X0000000000
X0000000110000000000000000000000110011000011000110000000000000011000001
X1000000000000000101100000000110000000000000001100000000000000000110000
X0000000000
X0000000110000000000000000000001100011000011000110000000000000011000001
X1000000000000000101100000001110000000000000111000000000000000000110000
X0000000000
X0000000111000000000000000000011100111000110001110000000000000011000001
X1000000000000001001100000001111000000000011110001000000000000000110000
X0000000000
X0000000011000000000000000000111000111000100001100000000000000011000001
X1000000000000011001100000011011000000001111000001100000000000000110000
X0000000000
X0000000011000000000000000001110000011011000001100000000000000011000001
X1100000000000010001100000110011100001111100000000110000000000000110000
X0000000000
X0000000001100000000000000111100000011111000001100000000000000011000100
X1100000000000110001100001100001111111110000000000111000000000001100000
X0000000000
X0000000001110000000000001110000000001100000011100000000000000001001100
X0111000000001100001100011000000111110000000000000011100000000011100000
X0000000000
X0000000000111100000001111100000000000000000011100000000000000001111000
X0011100000111000011000110000000000000000000000000001111000000111000000
X0000000000
X0000000000001111111111100000000000000000000011100000000000000001110000
X0001111111110000011001100000000000000000000000000000011111111110000000
X0000000000
X0000000000000011111110000000000000000000000000000000000000000000000000
X0000011111000000011011000000000000000000000000000000000111111100000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000000000011110000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000000000011100000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000000000111000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000000001111000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000000011011000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000000110011000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000001100011000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000011000011000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000001110000011000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000011100000011000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000111000000011000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000011110000000011000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000011000000000111000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0001110000000000110000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0001100000000000110000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0011100000000000110000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0111000000000000110000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0110000000000000110000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X1100000000000000110000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X1100000000000000110000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000001
X1000000000000001100000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000001
X1000000000000001100000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000011
X0000000000000001100000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000011
X0000000000000011000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000011
X0000000000000011000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000011
X0000000000000011000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000011
X0000000000000110000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000011
X0000000000000110000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000011
X0000000000000110000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000011
X0000000000001100000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000011
X0000000000001100000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000011
X0000000000011000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000001
X0000000000011000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000001
X1000000000110000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X1110000001100000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0111100111000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0001111110000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000011000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000000000000000000000000000000000000000000000000000000000000000
X0000000000

END_OF_FILE
echo shar: NEWLINE appended to \"'sign.pbm'\"
if test 15312 -ne `wc -c <'sign.pbm'`; then
    echo shar: \"'sign.pbm'\" unpacked with wrong size!
fi
# end of 'sign.pbm'
fi
echo shar: End of archive 1 \(of 2\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0