/* t1ascii
 *
 * This program takes an Adobe Type-1 font program in binary (PFB) format and
 * converts it to ASCII (PFA) format.
 *
 * Copyright (c) 1992 by I. Lee Hetherington, all rights reserved.
 *
 * Permission is hereby granted to use, modify, and distribute this program
 * for any purpose provided this copyright notice and the one below remain
 * intact. 
 *
 * I. Lee Hetherington (ilh@lcs.mit.edu)
 *
 * $Log:	t1ascii.c,v $
 * Revision 1.1  92/05/22  11:47:24  ilh
 * initial version
 * 
 */

#ifndef lint
static char rcsid[] =
  "@(#) $Id: t1ascii.c,v 1.1 92/05/22 11:47:24 ilh Exp $";
static char copyright[] =
  "@(#) Copyright (c) 1992 by I. Lee Hetherington, all rights reserved.";
#endif

/* Note: this is ANSI C. */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MARKER   128
#define ASCII    1
#define BINARY   2
#define DONE     3

static FILE *ifp = stdin;
static FILE *ofp = stdout;

/* This function reads a four-byte block length. */

static int read_length()
{
  int length;

  length = fgetc(ifp);
  length |= fgetc(ifp) << 8;
  length |= fgetc(ifp) << 16;
  length |= fgetc(ifp) << 24;

  return length;
}

/* This function outputs a single byte in hexadecimal.  It limits hexadecimal
   output to 64 columns. */

static void output_hex(int b)
{
  static char *hexchar = "0123456789ABCDEF";
  static int hexcol = 0;

  /* trim hexadecimal lines to 64 columns */
  if (hexcol >= 64) {
    fputc('\n', ofp);
    hexcol = 0;
  }
  fputc(hexchar[(b >> 4) & 0xf], ofp);
  fputc(hexchar[b & 0xf], ofp);
  hexcol += 2;
}

static void usage()
{
  fprintf(stderr,
	  "usage: t1ascii [input [output]]\n");
  exit(1);
}

static void print_banner()
{
  static char rcs_revision[] = "$Revision: 1.1 $";
  static char revision[20];

  if (sscanf(rcs_revision, "$Revision: %19s", revision) != 1)
    revision[0] = '\0';
  fprintf(stderr, "This is t1ascii %s.\n", revision);
}

int main(int argc, char **argv)
{
  int c, block = 1, length, last_type = ASCII;

  print_banner();

  if (argc > 3)
    usage();

  /* possibly open input & output files */
  if (argc >= 2) {
    ifp = fopen(argv[1], "r");
    if (!ifp) {
      fprintf(stderr, "error: cannot open %s for reading\n", argv[1]);
      exit(1);
    }
  }
  if (argc == 3) {
    ofp = fopen(argv[2], "w");
    if (!ofp) {
      fprintf(stderr, "error: cannot open %s for writing\n", argv[2]);
      exit(1);
    }
  }

  /* main loop through blocks */

  for (;;) {
    c = fgetc(ifp);
    if (c == EOF) {
      break;
    }
    if (c != MARKER) {
      fprintf(stderr,
	      "error:  missing marker (128) at beginning of block %d",
	      block);
      exit(1);
    }
    switch (c = fgetc(ifp)) {
    case ASCII:
      if (last_type != ASCII)
	fputc('\n', ofp);
      last_type = ASCII;
      for (length = read_length(); length > 0; length--)
	if ((c = fgetc(ifp)) == '\r')
	  fputc('\n', ofp);
	else
	  fputc(c, ofp);
      break;
    case BINARY:
      last_type = BINARY;
      for (length = read_length(); length > 0; length--)
	output_hex(fgetc(ifp));      
      break;
    case DONE:
      /* nothing to be done --- will exit at top of loop with EOF */
      break;
    default:
      fprintf(stderr, "error: bad block type %d in block %d\n",
	      c, block);
      break;
    }
    block++;
  }
  fclose(ifp);
  fclose(ofp);

  return 0;
}
