home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume5 / pbm3 / part2 / pbmtops.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-03  |  6.0 KB  |  287 lines

  1. /* pbmtops.c - read a portable bitmap and produce a PostScript bitmap file
  2. **
  3. ** Copyright (C) 1988 by Jef Poskanzer.
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. */
  12.  
  13. #include <stdio.h>
  14. #ifdef    OS_SYSV
  15. #include <string.h>
  16. #else    OS_SYSV
  17. #include <strings.h>
  18. #endif    OS_SYSV
  19. #include "pbm.h"
  20.  
  21. main( argc, argv )
  22. int argc;
  23. char *argv[];
  24.     {
  25.     FILE *ifd;
  26.     bit **bits;
  27.     int argn, rows, cols, padright, row, col;
  28.     char ch;
  29.     float scale;
  30.     char name[100], *cp;
  31.     char *usage = "usage:  %s [-s scale] [pbmfile]\n";
  32.  
  33.     argn = 1;
  34.     scale = 1.0;
  35.  
  36.     /* Check for flags. */
  37.     if ( argn < argc )
  38.     {
  39.     if ( argv[argn][0] == '-' )
  40.         {
  41.         if ( ( argv[argn][1] == 's' || argv[argn][1] == 'S' ) &&
  42.          argv[argn][2] == '\0' )
  43.         {
  44.         argn++;
  45.         if ( argn == argc )
  46.             {
  47.             fprintf( stderr, usage, argv[0] );
  48.             exit( 1 );
  49.             }
  50.         if ( sscanf( argv[argn], "%f", &scale ) != 1 )
  51.             {
  52.             fprintf( stderr, usage, argv[0] );
  53.             exit( 1 );
  54.             }
  55.         argn++;
  56.         }
  57.         else
  58.         {
  59.         fprintf( stderr, usage, argv[0] );
  60.         exit( 1 );
  61.         }
  62.         }
  63.     }
  64.  
  65.     if ( argn == argc )
  66.     {
  67.     ifd = stdin;
  68.     strcpy( name, "noname" );
  69.     }
  70.     else
  71.     {
  72.         ifd = fopen( argv[argn], "r" );
  73.         if ( ifd == NULL )
  74.         {
  75.         fprintf( stderr, "%s: can't open.\n", argv[argn] );
  76.         exit( 1 );
  77.         }
  78.     strcpy( name, argv[argn] );
  79.  
  80. #ifdef    OS_SYSV
  81.     if ( ( cp = strchr( name, '.' ) ) != 0 )
  82. #else    OS_SYSV
  83.     if ( ( cp = index( name, '.' ) ) != 0 )
  84. #endif    OS_SYSV
  85.         *cp = '\0';
  86.     argn++;
  87.     }
  88.  
  89.     if ( argn != argc )
  90.     {
  91.     fprintf( stderr, usage, argv[0] );
  92.     exit( 1 );
  93.     }
  94.  
  95.     bits = pbm_readpbm( ifd, &cols, &rows );
  96.  
  97.     if ( ifd != stdin )
  98.     fclose( ifd );
  99.     
  100.     /* Compute padding to round cols up to the nearest multiple of 8. */
  101.     padright = ( ( cols + 7 ) / 8 ) * 8 - cols;
  102.  
  103.     putinit( name, cols, rows, scale );
  104.     for ( row = 0; row < rows; row++ )
  105.     {
  106.         for ( col = 0; col < cols; col++ )
  107.         putbit( bits[row][col] );
  108.     for ( col = 0; col < padright; col++ )
  109.         putbit( 0 );
  110.         }
  111.     putrest( );
  112.  
  113.     exit( 0 );
  114.     }
  115.  
  116.  
  117. int item, bitsperitem, bitshift, rlitemsperline;
  118. int repeat, itembuf[128], count, repeatitem, repeatcount;
  119.  
  120. putinit( name, cols, rows, scale )
  121. char *name;
  122. int cols, rows;
  123. float scale;
  124.     {
  125.     int scols, srows;
  126.  
  127.     scols = cols * scale * 0.96 + 0.5;    /*   0.96 is the multiple of   */
  128.     srows = rows * scale * 0.96 + 0.5;    /* 72/300 that is closest to 1 */
  129.  
  130.     printf( "%%! %s.ps\n", name );
  131.     printf( "\n" );
  132.     printf( "/rlestr1 1 string def\n" );
  133.     printf( "/rlestr 128 string def\n" );
  134.     printf( "/readrlestring {\n" );
  135.     printf( "  currentfile rlestr1 readhexstring pop  0 get\n" );
  136.     printf( "  dup 127 le {\n" );
  137.     printf( "    currentfile rlestr 0  4 3 roll  1 add  getinterval\n" );
  138.     printf( "    readhexstring  pop\n" );
  139.     printf( "  } {\n" );
  140.     printf( "    256 exch sub  dup\n" );
  141.     printf( "    currentfile rlestr1 readhexstring pop  0 get\n" );
  142.     printf( "    exch 0 exch 1 exch 1 sub { rlestr exch 2 index put } for\n" );
  143.     printf( "    pop  rlestr exch 0 exch getinterval\n" );
  144.     printf( "  } ifelse\n" );
  145.     printf( "} bind def\n" );
  146.     printf( "\n" );
  147.     printf(
  148.     "%d %d translate\t%% move to lower left corner of box\n",
  149.     300 - ( scols/2 ), 400 - ( srows/2 ) );
  150.     printf( "%d %d scale\t\t%% scale box\n", scols, srows );
  151.     printf( "\n" );
  152.     printf( "%d %d 1\t\t\t%% width height bits/sample\n", cols, rows );
  153.     printf(
  154.     "[ %d 0 0 -%d 0 %d ]\t%% transformation matrix\n", cols, rows, rows );
  155.     printf( "{ readrlestring }\t%% proc\n" );
  156.     printf( "image\n" );
  157.  
  158.     rlitemsperline = 0;
  159.     item = 0;
  160.     bitsperitem = 0;
  161.     bitshift = 7;
  162.  
  163.     repeat = 1;
  164.     count = 0;
  165.     }
  166.  
  167. putrlitem( rlitem )
  168. int rlitem;
  169.     {
  170.     if ( rlitemsperline == 30 )
  171.     {
  172.     putchar( '\n' );
  173.     rlitemsperline = 0;
  174.     }
  175.     rlitemsperline++;
  176.     printf( "%02x", rlitem );
  177.     }
  178.  
  179. putrlbuffer( )
  180.     {
  181.     int i;
  182.  
  183.     if ( repeat )
  184.     {
  185.     putrlitem( 256 - count );
  186.     putrlitem( repeatitem );
  187.     }
  188.     else
  189.     {
  190.     putrlitem( count - 1 );
  191.     for ( i = 0; i < count; i++ )
  192.         putrlitem( itembuf[i] );
  193.     }
  194.     repeat = 1;
  195.     count = 0;
  196.     }
  197.  
  198. putitem( )
  199.     {
  200.     int i;
  201.  
  202.     if ( count == 128 )
  203.     putrlbuffer( );
  204.  
  205.     if ( repeat && count == 0 )
  206.     { /* Still initializing a repeat buf. */
  207.     itembuf[count] = repeatitem = item;
  208.     count++;
  209.     }
  210.     else if ( repeat )
  211.     { /* Repeating - watch for end of run. */
  212.     if ( item == repeatitem )
  213.         { /* Run continues. */
  214.         itembuf[count] = item;
  215.         count++;
  216.         }
  217.     else
  218.         { /* Run ended - is it long enough to dump? */
  219.         if ( count > 2 )
  220.         { /* Yes, dump a repeat-mode buffer and start a new one. */
  221.         putrlbuffer( );
  222.         itembuf[count] = repeatitem = item;
  223.         count++;
  224.         }
  225.         else
  226.         { /* Not long enough - convert to non-repeat mode. */
  227.         repeat = 0;
  228.         itembuf[count] = repeatitem = item;
  229.         count++;
  230.         repeatcount = 1;
  231.         }
  232.         }
  233.     }
  234.     else
  235.     { /* Not repeating - watch for a run worth repeating. */
  236.     if ( item == repeatitem )
  237.         { /* Possible run continues. */
  238.         repeatcount++;
  239.         if ( repeatcount > 3 )
  240.         { /* Long enough - dump non-repeat part and start repeat. */
  241.         count = count - ( repeatcount - 1 );
  242.         putrlbuffer( );
  243.         count = repeatcount;
  244.         for ( i = 0; i < count; i++ )
  245.             itembuf[i] = item;
  246.         }
  247.         else
  248.         { /* Not long enough yet - continue as non-repeat buf. */
  249.         itembuf[count] = item;
  250.         count++;
  251.         }
  252.         }
  253.     else
  254.         { /* Broken run. */
  255.         itembuf[count] = repeatitem = item;
  256.         count++;
  257.         repeatcount = 1;
  258.         }
  259.     }
  260.  
  261.     item = 0;
  262.     bitsperitem = 0;
  263.     bitshift = 7;
  264.     }
  265.  
  266. putbit( b )
  267. bit b;
  268.     {
  269.     if ( bitsperitem == 8 )
  270.     {
  271.     putitem( );
  272.     }
  273.     if ( ! b )
  274.     item += 1 << bitshift;
  275.     bitsperitem++;
  276.     bitshift--;
  277.     }
  278.  
  279. putrest( )
  280.     {
  281.     if ( bitsperitem > 0 )
  282.     putitem( );
  283.     if ( count > 0 )
  284.     putrlbuffer( );
  285.     printf( "\nshowpage\n" );
  286.     }
  287.