[comp.sys.amiga.tech] HP2IFF - Converts HPLaserJet Printer dumps to IFF Pictures

svermeulen%Ins.MRC.AdhocNet.CA@UNCAEDU.BITNET (Steve Vermeulen) (05/02/88)

Hi All,

       The following little program converts captured printer graphics
       dumps to IFF files for further processing.  This was written a
       while ago for the purpose of getting a brochure printed on a
       PostScript laser printer.  The process that was undertaken
       was:

              - Make brochure in PageSetter
              - run CMD
              - print brochure to HP LaserJet
              - convert captured output to IFF Pictures
                (approx. 2400x3300 pixels each)
              - use VPage to convert IFF Pics to PostScript
              - ARC PostScript files
              - put files on 5.25inch MS-DOS format disk

              - leave the Amiga World :-( and deARC files on
                a Compaq with harddisk and laser printer
              - squirt PostScript to Apple LaserWriter over
                9600 BAUD serial line (SLOW!!!!)

       thus demonstrating that the Amiga talks to both the PC and MAC
       Worlds :-)

                    Stephen Vermeulen
                    Author: Express Paint

------------------------  Cut Here ----------------------------------

/**************************************************************************
  HP2IFF.c

  Copyright 1988 By: Stephen Vermeulen

                 3635 Utah Dr. N.W.
                 Calgary, Alberta,
                 CANADA, T2N 4A6

                 (403) 282-7990

  Permission for non-commercial use and distribution is granted.

  This is a program that takes the output that would have been sent to an
  HP LaserJet Plus laser printer and converts it into a single bitplane IFF
  Picture.

  Syntax:  (from CLI ONLY)

     hp2iff input_file output_file

     The above will convert the contents of the captured printer output
     contained in the file "input_file" into an IFF ILBM Picture
     contained in the file "output_file".  You can use a program such
     as Carolyn Scheppner's CMD to capture the output of a graphics
     application as it is sent to the printer.  You should set the
     printer type to be an HP_LaserJet in Preferences.

     This is useful for capturing output from one application for
     further manipulation in a paint program (such as Express Paint)
     and for studying how the printer driver works.

Compiling:  This was done in MANX 3.4a

    cc hp2iff
    ln hp2iff -lc

  ...and that's all.  It should also work for Lattice without any problems:-)
***************************************************************************/

#include <stdio.h>

struct bmhd
{
  short w, h;
  short x, y;
  char nPlanes;
  char Masking;
  char compression;
  char pad1;
  short transparentColor;
  char xAspect, yAspect;
  short pageWidth, pageHeight;
};

struct bmhd mybmhd =
{
  1000, 1000,
  0, 0,
  1,
  0,
  0,
  0,
  0,
  10, 10,
  640, 400
};

#define MAKEID(a, b, c, d) (((a) << 24L) | ((b) << 16L) | ((c) << 8L) | (d))

#define BMHD MAKEID('B', 'M', 'H', 'D')
#define ILBM MAKEID('I', 'L', 'B', 'M')
#define BODY MAKEID('B', 'O', 'D', 'Y')
#define FORM MAKEID('F', 'O', 'R', 'M')

char buffer[2000];

write_LONG(file, value)
FILE *file;
long value;
{
  fwrite(&value, 4, 1, file);
}

/*************************************
  This function writes the initial
  IFF file header stuff, some vaules
  will not be correct initially, we
  will fseek() and correct them later.
**************************************/

write_preamble(file, bmhdptr)
FILE *file;
struct bmhd *bmhdptr;
{
  write_LONG(file, FORM);
  write_LONG(file, 0L);   /* wrong file length, correct later */
  write_LONG(file, ILBM);
  write_LONG(file, BMHD);
  write_LONG(file, (long) sizeof(struct bmhd));
  fwrite(bmhdptr, sizeof(struct bmhd), 1, file);  /* correct later */
  write_LONG(file, BODY);
  write_LONG(file, 0L);   /* correct later */
}

write_postamble(file, bmhdptr, length)
FILE *file;
struct bmhd *bmhdptr;
long length;
{
  fseek(file, 0L, 0);
  write_LONG(file, FORM);
  write_LONG(file, length - 8L);
  write_LONG(file, ILBM);
  write_LONG(file, BMHD);
  write_LONG(file, (long) sizeof(struct bmhd));
  fwrite(bmhdptr, sizeof(struct bmhd), 1, file);
  write_LONG(file, BODY);
  write_LONG(file, length - ftell(file) - 4L);
}

/*****************************************
  This is the routine that seeks foward to
  the next graphics row introducer.  It
  also returns the number of data bytes in
  the next row...  If it returns zero the
  end of file has been hit.

  graphics introducer is  "ESC*b"
  followed by a few acsii digits giving the
  row byte length, followed by 'W'.
******************************************/

find_graphics(file)
FILE *file;
{
  short data, lena, lenb, lenc, lend;

  while ((data = getc(file)) != EOF)
  {
    if (data != 0x01b)  /* get more if not an escape */
      continue;
    data = getc(file);
    if (data != '*') continue;  /* not the correct command */
    data = getc(file);
    if (data != 'b') continue;  /* not the correct command */

    /******************************
      now read in the data length
    ******************************/

    lena = getc(file);
    if (lena == 'W') continue;
    lenb = getc(file);
    if (lenb == 'W')
    {
      return(lena - '0');
    }
    lenc = getc(file);
    if (lenc == 'W')
    {
      return((lena - '0')*10 + (lenb - '0'));
    }
    lend = getc(file);
    if (lend == 'W')
    {
      return((lena - '0')*100 + (lenb - '0')*10 + (lenc - '0'));
    }
    printf("error 1\n");
    continue;
  }
  return(0);
}

main(argc, argv)
short argc;
char *argv[];
{
  short width, nrows, w;
  FILE *in, *out;

  if (argc == 3)
  {
    in = fopen(argv[1], "r");
    if (in)
    {
      out = fopen(argv[2], "w");
      if (out)
      {
        /************************************
          Files are open so now we write a
          standard IFF header chunk...
        *************************************/

        write_preamble(out, &mybmhd);

        /************************************
          Now read/process/write the input
          file.  Here we look for ESC*bXXXW
          strings which are the graphics
          header strings for each row of data
          and process these...
        *************************************/

        nrows = 0;
        while (width = find_graphics(in))
        {
          ++nrows;
          w = width;
          fread(buffer, width, 1, in);
          fwrite(buffer, width, 1, out);
          if (width & 0x01) putc(0, out);  /* pad a byte if odd length */
        }
        mybmhd.w = w << 3;
        mybmhd.h = nrows;
        write_postamble(out, &mybmhd, ftell(out));
        fclose(out);
      }
      fclose(in);
    }
  }
  else
  {
    printf("HP2IFF:  program to convert captured HP LaserJet Plus bitmap\n");
    printf("         picture dumps to standard IFF format\n");
    printf("Syntax:  HP2IFF capturefile IFFfilename\n");
    printf("\n) 1988 By Stephen Vermeulen  (403) 282-7990\n");
  }
}