home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / netpbma.zip / pgm / pgmtolispm.c < prev    next >
C/C++ Source or Header  |  1993-10-04  |  4KB  |  145 lines

  1. /* pgmtolispm.c - read a pgm and write a file acceptable to the 
  2. ** tv:read-bit-array-file function of TI Explorer and Symbolics Lisp Machines.
  3. **
  4. ** Written by Jamie Zawinski based on code (C) 1988 by Jef Poskanzer.
  5. **
  6. ** Permission to use, copy, modify, and distribute this software and its
  7. ** documentation for any purpose and without fee is hereby granted, provided
  8. ** that the above copyright notice appear in all copies and that both that
  9. ** copyright notice and this permission notice appear in supporting
  10. ** documentation.  This software is provided "as is" without express or
  11. ** implied warranty.
  12. **
  13. **   When one writes a multi-plane bitmap with tv:write-bit-array-file, it is
  14. **   usually a color image; but a color map is not written in the file, so we
  15. **   treat this as a graymap instead.  To convert a color image to Lispm 
  16. **   format, you must convert it to a pgm, and hand-edit a color map...  Ick.
  17. */
  18.  
  19. #include <stdio.h>
  20. #include "pgm.h"
  21.  
  22. #define LISPM_MAGIC  "This is a BitMap file"
  23.  
  24. static void putinit ARGS(( int cols, int rows, int depth ));
  25. static int depth_to_word_size ARGS(( int depth ));
  26. static void putval ARGS(( gray b ));
  27. static void putrest ARGS(( void ));
  28. static void putitem ARGS(( void ));
  29.  
  30. int
  31. main( argc, argv )
  32.     int argc;
  33.     char* argv[];
  34.     {
  35.     FILE* ifp;
  36.     gray *grayrow;
  37.     register gray* gP;
  38.     int rows, cols, depth, format, padright, row, col;
  39.     gray maxval;
  40.  
  41.  
  42.     pgm_init( &argc, argv );
  43.  
  44.     if ( argc > 2 )
  45.     pm_usage( "[pgmfile]" );
  46.     if ( argc == 2 )
  47.     ifp = pm_openr( argv[1] );
  48.     else
  49.     ifp = stdin;
  50.  
  51.     pgm_readpgminit( ifp, &cols, &rows, &maxval, &format );
  52.     grayrow = pgm_allocrow( cols );
  53.     depth = pm_maxvaltobits( maxval );
  54.  
  55.     /* Compute padding to round cols up to the nearest multiple of 32. */
  56.     padright = ( ( cols + 31 ) / 32 ) * 32 - cols;
  57.  
  58.     putinit( cols, rows, depth );
  59.     for ( row = 0; row < rows; ++row )
  60.     {
  61.     pgm_readpgmrow( ifp, grayrow, cols, maxval, format );
  62.         for ( col = 0, gP = grayrow; col < cols; ++col, ++gP )
  63.         putval( *gP );
  64.     for ( col = 0; col < padright; ++col )
  65.         putval( 0 );
  66.         }
  67.  
  68.     pm_close( ifp );
  69.  
  70.     putrest( );
  71.  
  72.     exit( 0 );
  73.     }
  74.  
  75. static unsigned int item;
  76. static unsigned int bitsperitem, maxbitsperitem, bitshift;
  77.  
  78. static void
  79. putinit( cols, rows, depth )
  80.     int cols, rows, depth;
  81.     {
  82.     int i;
  83.     int cols32 = ( ( cols + 31 ) / 32 ) * 32;    /* Lispms are able to write bit files that are not mod32 wide, but we   */
  84.                         /* don't.  This should be ok, since bit arrays which are not mod32 wide */
  85.     printf(LISPM_MAGIC);            /* are pretty useless on a lispm (can't hand them to bitblt).        */
  86.     pm_writelittleshort( stdout, cols );
  87.     pm_writelittleshort( stdout, rows );
  88.     pm_writelittleshort( stdout, cols32 );
  89.     putchar(depth & 0xFF);
  90.  
  91.     for ( i = 0; i < 9; ++i )
  92.     putchar( 0 );    /* pad bytes */
  93.  
  94.     item = 0;
  95.     bitsperitem = 0;
  96.     maxbitsperitem = depth_to_word_size( depth );
  97.     bitshift = 0;
  98.     }
  99.  
  100. static int
  101. depth_to_word_size (depth)    /* Lispm architecture specific - if a bitmap is written    */
  102.   int depth;            /* out with a depth of 5, it really has a depth of 8, and  */
  103. {                /* is stored that way in the file.               */
  104.     if (depth==0 || depth==1)    return ( 1);
  105.     else if (depth ==  2)    return ( 2);
  106.     else if (depth <=  4)    return ( 4);
  107.     else if (depth <=  8)    return ( 8);
  108.     else if (depth <= 16)    return (16);
  109.     else if (depth <= 32)    return (32);
  110.     else
  111.       pm_error( "depth was %d, which is not in the range 1-32", depth );
  112. }
  113.  
  114. #if __STDC__
  115. static void
  116. putval( gray b )
  117. #else /*__STDC__*/
  118. static void
  119. putval( b )
  120. gray b;
  121. #endif /*__STDC__*/
  122.     {
  123.     if ( bitsperitem == 32 )
  124.     putitem( );
  125.     item = item | ( b << bitshift );
  126.     bitsperitem = bitsperitem + maxbitsperitem;
  127.     bitshift = bitshift + maxbitsperitem;
  128.     }
  129.  
  130. static void
  131. putrest( )
  132.     {
  133.     if ( bitsperitem > 0 )
  134.     putitem( );
  135.     }
  136.  
  137. static void
  138. putitem( )
  139.     {
  140.     pm_writelittlelong( stdout, ~item );
  141.     item = 0;
  142.     bitsperitem = 0;
  143.     bitshift = 0;
  144.     }
  145.