home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / netpbma.zip / pbm / pbmtoln03.c < prev    next >
C/C++ Source or Header  |  1993-10-14  |  7KB  |  271 lines

  1. /*
  2. From tim@deakin.edu.au Fri May  7 00:18:57 1993
  3. From: Tim Cook <tim@deakin.edu.au>
  4. Date: Fri, 7 May 1993 15:18:34 -0500
  5. X-Mailer: Mail User's Shell (7.2.4 2/2/92)
  6. To: dyson@sunfish.Physics.UIowa.Edu
  7. Subject: Re: DEC LN03+ printer (not postscript) under SunOS (on SS10) ?
  8. Content-Length: 5893
  9.  
  10. In a message dated 6 May,  9:32, dyson@sunfish.Physics.UIowa.Edu
  11. (Richard L. Dyson) wrote:
  12. > > Just in case anyone is interested, I have a pbmtoln03 utility I wrote
  13. > > when I was mucking about with an LN03+.  If you are interested in
  14. > > printing your bitmaps at 300x300dpi, ask me for the source.
  15. >
  16. > I would be interested.  We still only have LN03+ printers on our VMS
  17. > machines here...
  18.  
  19. Ok, here goes.  Note that you will need the source from the pbmplus
  20. utilities, because my pbmtoln03 utility uses the library routines that
  21. are a part of pbmplus to read a PBM file (I linked it with libpbm.a).
  22. I have not tested this utility on VMS, but it looks like it should
  23. work.
  24. */
  25.  
  26. /* pbmtoln03.c -        Converts a PBM bitmap to DEC LN03 SIXEL bitmap
  27.  *
  28.  * SYNOPSIS
  29.  *      pbmtoln03 [pbm-file]
  30.  *
  31.  * OPTIONS
  32.  *      -l nn   Use "nn" as value for left margin (default 0).
  33.  *      -r nn   Use "nn" as value for right margin (default 2400).
  34.  *      -t nn   Use "nn" as value for top margin (default 0).
  35.  *      -b nn   Use "nn" as value for bottom margin (default 3400).
  36.  *      -f nn   Use "nn" as value for form length (default 3400).
  37.  *
  38.  * Tim Cook, 26 Feb 1992
  39.  * changed option parsing to PBM standards  - Ingo Wilken, 13 Oct 1993
  40.  */
  41.  
  42. #include <stdio.h>
  43. #include "pbm.h"
  44.  
  45. FILE *input ;
  46.  
  47. #ifndef print
  48. #define print(s)        fputs (s, stdout)
  49. #define fprint(f, s)    fputs (s, f)
  50. #endif
  51.  
  52. /* prototypes */
  53. void output_sixel_record ARGS((unsigned char *record, int width));
  54. void convert ARGS((int width, int height, int format));
  55.  
  56.  
  57. void output_sixel_record (record, width)
  58.    unsigned char *record ;
  59.    int width ;
  60. {
  61.    int i, j, k ;
  62.    unsigned char last_char ;
  63.    int start_repeat = 0 ;
  64.    int repeated ;
  65.    char repeated_str[16] ;
  66.    char *p ;
  67.  
  68.    /* Do RLE */
  69.    last_char = record[0] ;
  70.    j = 0 ;
  71.  
  72.    /* This will make the following loop complete */
  73.    record[width] = '\0' ;
  74.  
  75.    for (i = 1 ; i <= width ; i++) {
  76.  
  77.       repeated = i - start_repeat ;
  78.  
  79.       if (record[i] != last_char || repeated >= 32766) {
  80.  
  81.          /* Repeat has ended */
  82.  
  83.          if (repeated > 3) {
  84.  
  85.             /* Do an encoding */
  86.             record[j++] = '!' ;
  87.             sprintf (repeated_str, "%d", i - start_repeat) ;
  88.             for (p = repeated_str ; *p ; p++)
  89.                record[j++] = *p ;
  90.                record[j++] = last_char ; }
  91.  
  92.          else {
  93.             for (k = 0 ; k < repeated ; k++)
  94.                record[j++] = last_char ; }
  95.  
  96.          start_repeat = i ;
  97.          last_char = record[i] ; }
  98.       }
  99.  
  100.    fwrite ((char *) record, j, 1, stdout) ;
  101.    putchar ('-') ;      /* DECGNL (graphics new-line) */
  102.    putchar ('\n') ;
  103.    }
  104.  
  105.  
  106. void convert (width, height, format)
  107.    int width ;
  108.    int height ;
  109.    int format ;
  110. {
  111.    register i ;
  112.    unsigned char *sixel ;               /* A row of sixels */
  113.    int sixel_row ;
  114.  
  115.    bit *row = pbm_allocrow (width) ;
  116.  
  117.    sixel = (unsigned char *) malloc (width + 2) ;
  118.  
  119.    sixel_row = 0 ;
  120.    while (height--) {
  121.       pbm_readpbmrow (input, row, width, format) ;
  122.       switch (sixel_row) {
  123.          case 0 :
  124.            for (i = 0 ; i < width ; i++)
  125.               sixel[i] = row[i] ;
  126.            break ;
  127.          case 1 :
  128.            for (i = 0 ; i < width ; i++)
  129.               sixel[i] += row[i] << 1 ;
  130.            break ;
  131.          case 2 :
  132.            for (i = 0 ; i < width ; i++)
  133.               sixel[i] += row[i] << 2 ;
  134.            break ;
  135.          case 3 :
  136.            for (i = 0 ; i < width ; i++)
  137.               sixel[i] += row[i] << 3 ;
  138.            break ;
  139.          case 4 :
  140.            for (i = 0 ; i < width ; i++)
  141.               sixel[i] += row[i] << 4 ;
  142.            break ;
  143.          case 5 :
  144.            for (i = 0 ; i < width ; i++)
  145.               sixel[i] += (row[i] << 5) + 077 ;
  146.            output_sixel_record (sixel, width) ;
  147.            break ; }
  148.       if (sixel_row == 5)
  149.          sixel_row = 0 ;
  150.       else
  151.          sixel_row++ ;
  152.       }
  153.  
  154.    if (sixel_row > 0) {
  155.       /* Incomplete sixel record needs to be output */
  156.       for (i = 0 ; i < width ; i++)
  157.          sixel[i] += 077 ;
  158.       output_sixel_record (sixel, width) ; }
  159.    }
  160.  
  161.  
  162. int
  163. main (argc, argv)
  164.    int argc ;
  165.    char **argv ;
  166. {
  167.    int argc_copy = argc ;
  168.    char **argv_copy = argv ;
  169.    int ch ;
  170.    int argn;
  171.    char *usage = "[-left <nn>] [-right <nn>] [-top <nn>] [-bottom <nn>] [-formlength <nn>] [pbmfile]";
  172.  
  173.    /* Options */
  174.    /* These defaults are for a DEC LN03 with A4 paper (2400x3400 pixels) */
  175.    char *opt_left_margin = "0";
  176.    char *opt_top_margin = opt_left_margin;
  177.    char *opt_right_margin = "2400";
  178.    char *opt_bottom_margin = "3400";
  179.    char *opt_form_length = opt_bottom_margin;
  180.  
  181.    int width, height, format ;
  182.  
  183.  
  184.    pbm_init (&argc_copy, argv_copy) ;
  185.  
  186.    argn = 1;
  187.    while( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' ) {
  188.       if( pm_keymatch(argv[argn], "-left", 2) ) {
  189.          if( ++argn >= argc )
  190.             pm_usage(usage);
  191.          opt_left_margin = argv[argn];
  192.       }
  193.       else
  194.       if( pm_keymatch(argv[argn], "-right", 2) ) {
  195.          if( ++argn >= argc )
  196.             pm_usage(usage);
  197.          opt_right_margin = argv[argn];
  198.       }
  199.       else
  200.       if( pm_keymatch(argv[argn], "-top", 2) ) {
  201.          if( ++argn >= argc )
  202.             pm_usage(usage);
  203.          opt_top_margin = argv[argn];
  204.       }
  205.       else
  206.       if( pm_keymatch(argv[argn], "-bottom", 2) ) {
  207.          if( ++argn >= argc )
  208.             pm_usage(usage);
  209.          opt_bottom_margin = argv[argn];
  210.       }
  211.       else
  212.       if( pm_keymatch(argv[argn], "-formlength", 2) ) {
  213.          if( ++argn >= argc )
  214.             pm_usage(usage);
  215.          opt_form_length = argv[argn];
  216.       }
  217.       else
  218.          pm_usage(usage);
  219.       ++argn;
  220.    }
  221.  
  222.    if( argn < argc ) {
  223.       input = pm_openr( argv[argn] );
  224.       argn++;
  225.    }
  226.    else
  227.       input = stdin;
  228.  
  229.    if( argn != argc )
  230.       pm_usage(usage);
  231.  
  232.  
  233.    /* Initialise pbm file */
  234.    pbm_readpbminit (input, &width, &height, &format) ;
  235.  
  236. #ifdef notdef
  237.    fprintf (stderr, "width: %d, height: %d, format: %d\n", width,
  238.             height, format) ;
  239. #endif
  240.  
  241.    if (format != PBM_FORMAT && format != RPBM_FORMAT)
  242.       pm_error ("input not in PBM format") ;
  243.  
  244. /*
  245.  * In explanation of the sequence below:
  246.  *      <ESC>[!p        DECSTR  soft terminal reset
  247.  *      <ESC>[11h       PUM     select unit of measurement
  248.  *      <ESC>[7 I       SSU     select pixel as size unit
  249.  *      <ESC>[?52l      DECOPM  origin is corner of printable area
  250.  *      <ESC>[%s;%ss    DECSLRM left and right margins
  251.  *      <ESC>[%s;%sr    DECSTBM top and bottom margins
  252.  *      <ESC>[%st       DECSLPP form length
  253.  *      <ESC>P0;0;1q            select sixel graphics mode
  254.  *      "1;1            DECGRA  aspect ratio (1:1)
  255.  */
  256.  
  257.    /* Initialise sixel file */
  258.    printf (
  259. "\033[!p\033[11h\033[7 I\033[?52l\033[%s;%ss\033[%s;%sr\033[%st\033P0;0;1q\"1;1",
  260.       opt_left_margin, opt_right_margin, opt_top_margin, opt_bottom_margin,
  261.       opt_form_length);
  262.  
  263.    /* Convert data */
  264.    convert (width, height, format) ;
  265.  
  266.    /* Terminate sixel data */
  267.    print ("\033\\\n") ;
  268.    }
  269.  
  270.  
  271.