Blame converter/pbm/pbmtoln03.c

Packit 78deda
/*
Packit 78deda
From tim@deakin.edu.au Fri May  7 00:18:57 1993
Packit 78deda
From: Tim Cook <tim@deakin.edu.au>
Packit 78deda
Date: Fri, 7 May 1993 15:18:34 -0500
Packit 78deda
X-Mailer: Mail User's Shell (7.2.4 2/2/92)
Packit 78deda
To: dyson@sunfish.Physics.UIowa.Edu
Packit 78deda
Subject: Re: DEC LN03+ printer (not postscript) under SunOS (on SS10) ?
Packit 78deda
Content-Length: 5893
Packit 78deda
Packit 78deda
In a message dated 6 May,  9:32, dyson@sunfish.Physics.UIowa.Edu
Packit 78deda
(Richard L. Dyson) wrote:
Packit 78deda
> > Just in case anyone is interested, I have a pbmtoln03 utility I wrote
Packit 78deda
> > when I was mucking about with an LN03+.  If you are interested in
Packit 78deda
> > printing your bitmaps at 300x300dpi, ask me for the source.
Packit 78deda
>
Packit 78deda
> I would be interested.  We still only have LN03+ printers on our VMS
Packit 78deda
> machines here...
Packit 78deda
Packit 78deda
Ok, here goes.  Note that you will need the source from the pbmplus
Packit 78deda
utilities, because my pbmtoln03 utility uses the library routines that
Packit 78deda
are a part of pbmplus to read a PBM file (I linked it with libpbm.a).
Packit 78deda
I have not tested this utility on VMS, but it looks like it should
Packit 78deda
work.
Packit 78deda
*/
Packit 78deda
Packit 78deda
/* pbmtoln03.c -        Converts a PBM bitmap to DEC LN03 SIXEL bitmap
Packit 78deda
 *
Packit 78deda
 * SYNOPSIS
Packit 78deda
 *      pbmtoln03 [pbm-file]
Packit 78deda
 *
Packit 78deda
 * OPTIONS
Packit 78deda
 *      -l nn   Use "nn" as value for left margin (default 0).
Packit 78deda
 *      -r nn   Use "nn" as value for right margin (default 2400).
Packit 78deda
 *      -t nn   Use "nn" as value for top margin (default 0).
Packit 78deda
 *      -b nn   Use "nn" as value for bottom margin (default 3400).
Packit 78deda
 *      -f nn   Use "nn" as value for form length (default 3400).
Packit 78deda
 *
Packit 78deda
 * Tim Cook, 26 Feb 1992
Packit 78deda
 * changed option parsing to PBM standards  - Ingo Wilken, 13 Oct 1993
Packit 78deda
 */
Packit 78deda
Packit 78deda
#include <stdio.h>
Packit 78deda
#include "pbm.h"
Packit 78deda
Packit 78deda
FILE *input ;
Packit 78deda
Packit 78deda
#ifndef print
Packit 78deda
#define print(s)        fputs (s, stdout)
Packit 78deda
#define fprint(f, s)    fputs (s, f)
Packit 78deda
#endif
Packit 78deda
Packit 78deda
Packit 78deda
static void 
Packit 78deda
output_sixel_record (unsigned char * record, int width) {
Packit 78deda
Packit 78deda
   int i, j, k ;
Packit 78deda
   unsigned char last_char ;
Packit 78deda
   int start_repeat = 0 ;
Packit 78deda
   int repeated ;
Packit 78deda
   char repeated_str[16] ;
Packit 78deda
   char *p ;
Packit 78deda
Packit 78deda
   /* Do RLE */
Packit 78deda
   last_char = record[0] ;
Packit 78deda
   j = 0 ;
Packit 78deda
Packit 78deda
   /* This will make the following loop complete */
Packit 78deda
   record[width] = '\0' ;
Packit 78deda
Packit 78deda
   for (i = 1 ; i <= width ; i++) {
Packit 78deda
Packit 78deda
      repeated = i - start_repeat ;
Packit 78deda
Packit 78deda
      if (record[i] != last_char || repeated >= 32766) {
Packit 78deda
Packit 78deda
         /* Repeat has ended */
Packit 78deda
Packit 78deda
         if (repeated > 3) {
Packit 78deda
Packit 78deda
            /* Do an encoding */
Packit 78deda
            record[j++] = '!' ;
Packit 78deda
            sprintf (repeated_str, "%d", i - start_repeat) ;
Packit Service 2370ca
            for (p = repeated_str ; *p ; p++)
Packit 78deda
               record[j++] = *p ;
Packit Service 2370ca
               record[j++] = last_char ; }
Packit 78deda
Packit Service 2370ca
         else {
Packit 78deda
            for (k = 0 ; k < repeated ; k++)
Packit Service 2370ca
               record[j++] = last_char ; }
Packit 78deda
Packit 78deda
         start_repeat = i ;
Packit Service 2370ca
         last_char = record[i] ; }
Packit 78deda
      }
Packit 78deda
Packit 78deda
   fwrite ((char *) record, j, 1, stdout) ;
Packit 78deda
   putchar ('-') ;      /* DECGNL (graphics new-line) */
Packit 78deda
   putchar ('\n') ;
Packit Service 2370ca
   }
Packit 78deda
Packit 78deda
Packit 78deda
static void 
Packit 78deda
convert (int width, int height, int format) {
Packit 78deda
Packit 78deda
   int i ;
Packit 78deda
   unsigned char *sixel ;               /* A row of sixels */
Packit 78deda
   int sixel_row ;
Packit 78deda
Packit 78deda
   bit *row = pbm_allocrow (width) ;
Packit 78deda
Packit 78deda
   sixel = (unsigned char *) malloc (width + 2) ;
Packit 78deda
Packit 78deda
   sixel_row = 0 ;
Packit 78deda
   while (height--) {
Packit 78deda
      pbm_readpbmrow (input, row, width, format) ;
Packit 78deda
      switch (sixel_row) {
Packit 78deda
         case 0 :
Packit 78deda
           for (i = 0 ; i < width ; i++)
Packit 78deda
              sixel[i] = row[i] ;
Packit 78deda
           break ;
Packit 78deda
         case 1 :
Packit 78deda
           for (i = 0 ; i < width ; i++)
Packit 78deda
              sixel[i] += row[i] << 1 ;
Packit 78deda
           break ;
Packit 78deda
         case 2 :
Packit 78deda
           for (i = 0 ; i < width ; i++)
Packit 78deda
              sixel[i] += row[i] << 2 ;
Packit 78deda
           break ;
Packit 78deda
         case 3 :
Packit 78deda
           for (i = 0 ; i < width ; i++)
Packit 78deda
              sixel[i] += row[i] << 3 ;
Packit 78deda
           break ;
Packit 78deda
         case 4 :
Packit 78deda
           for (i = 0 ; i < width ; i++)
Packit 78deda
              sixel[i] += row[i] << 4 ;
Packit 78deda
           break ;
Packit 78deda
         case 5 :
Packit 78deda
           for (i = 0 ; i < width ; i++)
Packit 78deda
              sixel[i] += (row[i] << 5) + 077 ;
Packit 78deda
           output_sixel_record (sixel, width) ;
Packit 78deda
           break ; }
Packit 78deda
      if (sixel_row == 5)
Packit 78deda
         sixel_row = 0 ;
Packit 78deda
      else
Packit 78deda
         sixel_row++ ;
Packit 78deda
      }
Packit 78deda
Packit 78deda
   if (sixel_row > 0) {
Packit 78deda
      /* Incomplete sixel record needs to be output */
Packit 78deda
      for (i = 0 ; i < width ; i++)
Packit 78deda
         sixel[i] += 077 ;
Packit 78deda
      output_sixel_record (sixel, width) ; }
Packit 78deda
   }
Packit 78deda
Packit 78deda
Packit 78deda
Packit 78deda
int
Packit 78deda
main (int argc, char **argv) {
Packit 78deda
   int argc_copy = argc ;
Packit 78deda
   char **argv_copy = argv ;
Packit 78deda
   int argn;
Packit 78deda
   const char * const usage = "[-left <nn>] [-right <nn>] [-top <nn>] "
Packit 78deda
       "[-bottom <nn>] [-formlength <nn>] [pbmfile]";
Packit 78deda
Packit 78deda
   /* Options */
Packit 78deda
   /* These defaults are for a DEC LN03 with A4 paper (2400x3400 pixels) */
Packit 78deda
   const char *opt_left_margin = "0";
Packit 78deda
   const char *opt_top_margin = opt_left_margin;
Packit 78deda
   const char *opt_right_margin = "2400";
Packit 78deda
   const char *opt_bottom_margin = "3400";
Packit 78deda
   const char *opt_form_length = opt_bottom_margin;
Packit 78deda
Packit 78deda
   int width, height, format ;
Packit 78deda
Packit 78deda
   pbm_init (&argc_copy, argv_copy) ;
Packit 78deda
Packit 78deda
   argn = 1;
Packit 78deda
   while( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' ) {
Packit 78deda
      if( pm_keymatch(argv[argn], "-left", 2) ) {
Packit 78deda
         if( ++argn >= argc )
Packit 78deda
            pm_usage(usage);
Packit 78deda
         opt_left_margin = argv[argn];
Packit 78deda
      }
Packit 78deda
      else
Packit 78deda
      if( pm_keymatch(argv[argn], "-right", 2) ) {
Packit 78deda
         if( ++argn >= argc )
Packit 78deda
            pm_usage(usage);
Packit 78deda
         opt_right_margin = argv[argn];
Packit 78deda
      }
Packit 78deda
      else
Packit 78deda
      if( pm_keymatch(argv[argn], "-top", 2) ) {
Packit 78deda
         if( ++argn >= argc )
Packit 78deda
            pm_usage(usage);
Packit 78deda
         opt_top_margin = argv[argn];
Packit 78deda
      }
Packit 78deda
      else
Packit 78deda
      if( pm_keymatch(argv[argn], "-bottom", 2) ) {
Packit 78deda
         if( ++argn >= argc )
Packit 78deda
            pm_usage(usage);
Packit 78deda
         opt_bottom_margin = argv[argn];
Packit 78deda
      }
Packit 78deda
      else
Packit 78deda
      if( pm_keymatch(argv[argn], "-formlength", 2) ) {
Packit 78deda
         if( ++argn >= argc )
Packit 78deda
            pm_usage(usage);
Packit 78deda
         opt_form_length = argv[argn];
Packit 78deda
      }
Packit 78deda
      else
Packit 78deda
         pm_usage(usage);
Packit 78deda
      ++argn;
Packit 78deda
   }
Packit 78deda
Packit 78deda
   if( argn < argc ) {
Packit 78deda
      input = pm_openr( argv[argn] );
Packit 78deda
      argn++;
Packit 78deda
   }
Packit 78deda
   else
Packit 78deda
      input = stdin;
Packit 78deda
Packit 78deda
   if( argn != argc )
Packit 78deda
      pm_usage(usage);
Packit 78deda
Packit 78deda
   pbm_readpbminit (input, &width, &height, &format) ;
Packit 78deda
Packit 78deda
/*
Packit 78deda
 * In explanation of the sequence below:
Packit 78deda
 *      <ESC>[!p        DECSTR  soft terminal reset
Packit 78deda
 *      <ESC>[11h       PUM     select unit of measurement
Packit 78deda
 *      <ESC>[7 I       SSU     select pixel as size unit
Packit 78deda
 *      <ESC>[?52l      DECOPM  origin is corner of printable area
Packit 78deda
 *      <ESC>[%s;%ss    DECSLRM left and right margins
Packit 78deda
 *      <ESC>[%s;%sr    DECSTBM top and bottom margins
Packit 78deda
 *      <ESC>[%st       DECSLPP form length
Packit 78deda
 *      <ESC>P0;0;1q            select sixel graphics mode
Packit 78deda
 *      "1;1            DECGRA  aspect ratio (1:1)
Packit 78deda
 */
Packit 78deda
Packit 78deda
   /* Initialize sixel file */
Packit 78deda
   printf ("\033[!p\033[11h\033[7 I\033[?52l\033[%s;%ss\033"
Packit 78deda
           "[%s;%sr\033[%st\033P0;0;1q\"1;1",
Packit 78deda
      opt_left_margin, opt_right_margin, opt_top_margin, opt_bottom_margin,
Packit 78deda
      opt_form_length);
Packit 78deda
Packit 78deda
   /* Convert data */
Packit 78deda
   convert (width, height, format) ;
Packit 78deda
Packit 78deda
   /* Terminate sixel data */
Packit 78deda
   print ("\033\\\n") ;
Packit 78deda
Packit 78deda
   /* If the program failed, it previously aborted with nonzero completion
Packit 78deda
      code, via various function calls.
Packit 78deda
   */
Packit 78deda
   return 0;
Packit 78deda
}
Packit 78deda
Packit 78deda