home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / gnulib / dkbtrace / pbmplus / source / pgm / lispmtop.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-10  |  5.3 KB  |  161 lines

  1. /* lispmtopgm.c - read a file written by the tv:write-bit-array-file function
  2. ** of TI Explorer and Symbolics Lisp Machines, and write a PGM.
  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.  Since the pgm reader can also read pbms,
  16. **   this doesn't matter if you're using only single plane images.
  17. */
  18.  
  19. #include <stdio.h>
  20. #include "pgm.h"
  21.  
  22. #define LISPM_MAGIC  "This is a BitMap file"
  23.  
  24. static void getinit ARGS(( FILE* file, short* colsP, short* rowsP, short* depthP, short* padrightP ));
  25. static int depth_to_word_size ARGS(( int depth ));
  26. static unsigned int getval ARGS(( FILE* file ));
  27.  
  28. void
  29. main( argc, argv )
  30.     int argc;
  31.     char* argv[];
  32.     {
  33.     FILE* ifp;
  34.     gray* grayrow;
  35.     register gray* gP;
  36.     short rows, cols, padright, row, col;
  37.     short depth;
  38.     int maxval;
  39.  
  40.     pgm_init( &argc, argv );
  41.  
  42.     if ( argc > 2 )
  43.     pm_usage( "[lispmfile]" );
  44.  
  45.     if ( argc == 2 )
  46.         ifp = pm_openr( argv[1] );
  47.     else
  48.     ifp = stdin;
  49.  
  50.     getinit( ifp, &cols, &rows, &depth, &padright );
  51.     maxval = 1 << depth;
  52.  
  53.     if ( maxval > PGM_MAXMAXVAL )
  54.     pm_error( "depth is too large - try reconfiguring with PGM_BIGGRAYS" );
  55.  
  56.     pgm_writepgminit( stdout, cols, rows, (gray) maxval, 0 );
  57.     grayrow = pgm_allocrow( ( cols + 7 ) / 8 * 8 );
  58.  
  59.     for ( row = 0; row < rows; ++row )
  60.     {
  61.         for ( col = 0, gP = grayrow; col < cols; ++col, ++gP )
  62.         *gP = getval( ifp );
  63.     pgm_writepgmrow( stdout, grayrow, cols, (gray) maxval, 0 );
  64.     }
  65.     pm_close( ifp );
  66.     pm_close( stdout );
  67.     exit( 0 );
  68.     }
  69.  
  70. static long item, bitmask;
  71. static unsigned int bitsperitem, maxbitsperitem, bitshift;
  72.  
  73. static void
  74. getinit( file, colsP, rowsP, depthP, padrightP )
  75.     FILE* file;
  76.     short* colsP;
  77.     short* rowsP;
  78.     short* padrightP;
  79.     short* depthP;
  80.     {
  81.     short cols_32;
  82.     char magic[sizeof(LISPM_MAGIC)];
  83.     int i;
  84.  
  85.     for ( i = 0; i < sizeof(magic)-1; ++i )
  86.         magic[i] = getc( file );
  87.     magic[i]='\0';
  88.     if (0 != strcmp(LISPM_MAGIC, magic))
  89.         pm_error( "bad id string in Lispm file" );
  90.     
  91.     if ( pm_readlittleshort( file, colsP ) == -1 )
  92.         pm_error( "EOF / read error" );
  93.     if ( pm_readlittleshort( file, rowsP ) == -1 )
  94.         pm_error( "EOF / read error" );
  95.     if ( pm_readlittleshort( file, &cols_32 ) == -1 )
  96.         pm_error( "EOF / read error" );
  97.     *depthP = getc( file );
  98.     
  99.     if ( *depthP == 0 )
  100.     *depthP = 1;    /* very old file */
  101.     
  102.     *padrightP = ( ( *colsP + 31 ) / 32 ) * 32 - *colsP;
  103.     
  104.     if ( *colsP != (cols_32 - *padrightP) ) {
  105. /*    pm_message( "inconsistent input: Width and Width(mod32) fields don't agree" );  */
  106. /*    *padrightP = cols_32 - *colsP;   */ /*    hmmmm....   */
  107.       /* This is a dilemma.  Usually the output is rounded up to mod32, but not always.
  108.        * For the Lispm code to not round up, the array size must be the same size as the
  109.        * portion being written - that is, the array itself must be an odd size, not just
  110.        * the selected portion.  Since arrays that are odd sizes can't be handed to bitblt,
  111.        * such arrays are probably not image data - so punt on it for now.
  112.        *
  113.        * Also, the lispm code for saving bitmaps has a bug, in that if you are writing a
  114.        * bitmap which is not mod32 across, the file may be up to 7 bits too short!  They
  115.        * round down instead of up.
  116.        *
  117.        * The code in 'pgmtolispm.c' always rounds up to mod32, which is totally reasonable.
  118.        */
  119.       }
  120.     bitsperitem = 0;
  121.     maxbitsperitem = depth_to_word_size( *depthP );
  122.     bitmask = ( 1 << maxbitsperitem ) - 1;        /* for depth=3, mask=00000111 */
  123.  
  124.     for ( i = 0; i < 9; ++i )
  125.     getc( file );    /* discard bytes reserved for future use */
  126.     }
  127.  
  128. static int
  129. depth_to_word_size (depth)    /* Lispm architecture specific - if a bitmap is written    */
  130.   int depth;            /* out with a depth of 5, it really has a depth of 8, and  */
  131. {                /* is stored that way in the file.               */
  132.     if (depth==0 || depth==1)    return ( 1);
  133.     else if (depth ==  2)    return ( 2);
  134.     else if (depth <=  4)    return ( 4);
  135.     else if (depth <=  8)    return ( 8);
  136.     else if (depth <= 16)    return (16);
  137.     else if (depth <= 32)    return (32);
  138.     else
  139.       pm_error( "depth was %d, which is not in the range 1-32.", depth );
  140. }
  141.  
  142. static unsigned int
  143. getval( file )
  144.     FILE* file;
  145.     {
  146.     unsigned int b;
  147.  
  148.     if ( bitsperitem == 0 )
  149.     {
  150.     if ( pm_readlittlelong( file, &item ) == -1 )
  151.         pm_error( "EOF / read error" );
  152.     bitsperitem = 32;
  153.     bitshift = 0;
  154.     item = ~item;
  155.     }
  156.     b = ( ( item >> bitshift ) & bitmask );
  157.     bitsperitem = bitsperitem - maxbitsperitem;
  158.     bitshift = bitshift + maxbitsperitem;
  159.     return b;
  160.     }
  161.