home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / gnulib / dkbtrace / pbmplus / source / pgm / pgmtolis.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-06  |  4.1 KB  |  146 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. void
  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.     pgm_init( &argc, argv );
  42.  
  43.     if ( argc > 2 )
  44.     pm_usage( "[pgmfile]" );
  45.     if ( argc == 2 )
  46.     ifp = pm_openr( argv[1] );
  47.     else
  48.     ifp = stdin;
  49.  
  50.     pgm_readpgminit( ifp, &cols, &rows, &maxval, &format );
  51.     grayrow = pgm_allocrow( cols );
  52.     depth = pm_maxvaltobits( maxval );
  53.  
  54.     /* Compute padding to round cols up to the nearest multiple of 32. */
  55.     padright = ( ( cols + 31 ) / 32 ) * 32 - cols;
  56.  
  57.     putinit( cols, rows, depth );
  58.     for ( row = 0; row < rows; ++row )
  59.     {
  60.     pgm_readpgmrow( ifp, grayrow, cols, maxval, format );
  61.         for ( col = 0, gP = grayrow; col < cols; ++col, ++gP )
  62.         putval( *gP );
  63.     for ( col = 0; col < padright; ++col )
  64.         putval( 0 );
  65.         }
  66.  
  67.     pm_close( ifp );
  68.  
  69.     putrest( );
  70.  
  71.     pm_close (stdout);
  72.  
  73.     exit( 0 );
  74.     }
  75.  
  76. static unsigned int item;
  77. static unsigned int bitsperitem, maxbitsperitem, bitshift;
  78.  
  79. static void
  80. putinit( cols, rows, depth )
  81.     int cols, rows, depth;
  82.     {
  83.     int i;
  84.     int cols32 = ( ( cols + 31 ) / 32 ) * 32;    /* Lispms are able to write bit files that are not mod32 wide, but we   */
  85.                         /* don't.  This should be ok, since bit arrays which are not mod32 wide */
  86.     fprintf (stdout, LISPM_MAGIC);            /* are pretty useless on a lispm (can't hand them to bitblt).        */
  87.     pm_writelittleshort( stdout, cols );
  88.     pm_writelittleshort( stdout, rows );
  89.     pm_writelittleshort( stdout, cols32 );
  90.     putchar(depth & 0xFF);
  91.  
  92.     for ( i = 0; i < 9; ++i )
  93.     putchar( 0 );    /* pad bytes */
  94.  
  95.     item = 0;
  96.     bitsperitem = 0;
  97.     maxbitsperitem = depth_to_word_size( depth );
  98.     bitshift = 0;
  99.     }
  100.  
  101. static int
  102. depth_to_word_size (depth)    /* Lispm architecture specific - if a bitmap is written    */
  103.   int depth;            /* out with a depth of 5, it really has a depth of 8, and  */
  104. {                /* is stored that way in the file.               */
  105.     if (depth==0 || depth==1)    return ( 1);
  106.     else if (depth ==  2)    return ( 2);
  107.     else if (depth <=  4)    return ( 4);
  108.     else if (depth <=  8)    return ( 8);
  109.     else if (depth <= 16)    return (16);
  110.     else if (depth <= 32)    return (32);
  111.     else
  112.       pm_error( "depth was %d, which is not in the range 1-32", depth );
  113. }
  114.  
  115. #if __STDC__
  116. static void
  117. putval( gray b )
  118. #else /*__STDC__*/
  119. static void
  120. putval( b )
  121. gray b;
  122. #endif /*__STDC__*/
  123.     {
  124.     if ( bitsperitem == 32 )
  125.     putitem( );
  126.     item = item | ( b << bitshift );
  127.     bitsperitem = bitsperitem + maxbitsperitem;
  128.     bitshift = bitshift + maxbitsperitem;
  129.     }
  130.  
  131. static void
  132. putrest( )
  133.     {
  134.     if ( bitsperitem > 0 )
  135.     putitem( );
  136.     }
  137.  
  138. static void
  139. putitem( )
  140.     {
  141.     pm_writelittlelong( stdout, ~item );
  142.     item = 0;
  143.     bitsperitem = 0;
  144.     bitshift = 0;
  145.     }
  146.