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

  1. /* xbmtopbm.c - read an X bitmap file and produce a portable bitmap
  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 "pbm.h"
  14.  
  15. static void ReadBitmapFile ARGS(( FILE* stream, int* widthP, int* heightP, char** dataP ));
  16.  
  17. int
  18. main( argc, argv )
  19.     int argc;
  20.     char* argv[];
  21.     {
  22.     FILE* ifp;
  23.     bit* bitrow;
  24.     register bit* bP;
  25.     int rows, cols, row, col, charcount;
  26.     char* data;
  27.     char mask;
  28.  
  29.     pbm_init( &argc, argv );
  30.  
  31.     if ( argc > 2 )
  32.     pm_usage( "[bitmapfile]" );
  33.     
  34.     if ( argc == 2 )
  35.     ifp = pm_openr( argv[1] );
  36.     else
  37.     ifp = stdin;
  38.  
  39.     ReadBitmapFile( ifp, &cols, &rows, &data );
  40.  
  41.     pm_close( ifp );
  42.  
  43.     pbm_writepbminit( stdout, cols, rows, 0 );
  44.     bitrow = pbm_allocrow( cols );
  45.  
  46.     for ( row = 0; row < rows; ++row )
  47.     {
  48.     charcount = 0;
  49.     mask = 1;
  50.     for ( col = 0, bP = bitrow; col < cols; ++col, ++bP )
  51.         {
  52.         if ( charcount >= 8 )
  53.         {
  54.         ++data;
  55.         charcount = 0;
  56.         mask = 1;
  57.         }
  58.         *bP = ( *data & mask ) ? PBM_BLACK : PBM_WHITE;
  59.         ++charcount;
  60.         mask = mask << 1;
  61.         }
  62.     ++data;
  63.     pbm_writepbmrow( stdout, bitrow, cols, 0 );
  64.     }
  65.  
  66.     pm_close( stdout );
  67.     exit( 0 );
  68.     }
  69.  
  70. #define MAX_LINE 500
  71.  
  72. static void
  73. ReadBitmapFile( stream, widthP, heightP, dataP )
  74.     FILE* stream;
  75.     int* widthP;
  76.     int* heightP;
  77.     char** dataP;
  78.     {
  79.     char line[MAX_LINE], name_and_type[MAX_LINE];
  80.     char* ptr;
  81.     char* t;
  82.     int version10, raster_length, v;
  83.     register int bytes, bytes_per_line, padding;
  84.     register int c1, c2, value1, value2;
  85.     int hex_table[256];
  86.  
  87.     *widthP = *heightP = -1;
  88.  
  89.     for ( ; ; )
  90.     {
  91.     if ( fgets( line, MAX_LINE, stream ) == NULL )
  92.         pm_error( "EOF / read error" );
  93.     if ( strlen( line ) == MAX_LINE - 1 )
  94.         pm_error( "line too long" );
  95.  
  96.     if ( sscanf( line, "#define %s %d", name_and_type, &v ) == 2 )
  97.         {
  98.         if ( ( t = rindex( name_and_type, '_' ) ) == NULL )
  99.         t = name_and_type;
  100.         else
  101.         ++t;
  102.         if ( ! strcmp( "width", t ) )
  103.         *widthP = v;
  104.         else if ( ! strcmp( "height", t ) )
  105.         *heightP = v;
  106.         continue;
  107.         }
  108.     
  109.     if ( sscanf( line, "static short %s = {", name_and_type ) == 1 ) /* } */
  110.         {
  111.         version10 = 1;
  112.         break;
  113.         }
  114.     if ( sscanf( line, "static char %s = {", name_and_type ) == 1 ) /* } */
  115.         {
  116.         version10 = 0;
  117.         break;
  118.         }
  119.     }
  120.  
  121.     if ( *widthP == -1 )
  122.     pm_error( "invalid width" );
  123.     if ( *heightP == -1 )
  124.     pm_error( "invalid height" );
  125.  
  126.     padding = 0;
  127.     if ( ((*widthP % 16) >= 1) && ((*widthP % 16) <= 8) && version10 )
  128.     padding = 1;
  129.  
  130.     bytes_per_line = (*widthP+7)/8 + padding;
  131.     
  132.     raster_length =  bytes_per_line * *heightP;
  133.     *dataP = (char*) malloc( raster_length );
  134.     if ( *dataP == (char*) 0 )
  135.     pm_error( "out of memory" );
  136.  
  137.     /* Initialize hex_table. */
  138.     for ( c1 = 0; c1 < 256; ++c1 )
  139.     hex_table[c1] = 256;
  140.     hex_table['0'] = 0;
  141.     hex_table['1'] = 1;
  142.     hex_table['2'] = 2;
  143.     hex_table['3'] = 3;
  144.     hex_table['4'] = 4;
  145.     hex_table['5'] = 5;
  146.     hex_table['6'] = 6;
  147.     hex_table['7'] = 7;
  148.     hex_table['8'] = 8;
  149.     hex_table['9'] = 9;
  150.     hex_table['A'] = 10;
  151.     hex_table['B'] = 11;
  152.     hex_table['C'] = 12;
  153.     hex_table['D'] = 13;
  154.     hex_table['E'] = 14;
  155.     hex_table['F'] = 15;
  156.     hex_table['a'] = 10;
  157.     hex_table['b'] = 11;
  158.     hex_table['c'] = 12;
  159.     hex_table['d'] = 13;
  160.     hex_table['e'] = 14;
  161.     hex_table['f'] = 15;
  162.  
  163.     if ( version10 )
  164.     for ( bytes = 0, ptr = *dataP; bytes < raster_length; bytes += 2 )
  165.         {
  166.         while ( ( c1 = getc( stream ) ) != 'x' )
  167.             if ( c1 == EOF )
  168.             pm_error( "EOF / read error" );
  169.         c1 = getc( stream );
  170.         c2 = getc( stream );
  171.         if ( c1 == EOF || c2 == EOF )
  172.         pm_error( "EOF / read error" );
  173.         value1 = ( hex_table[c1] << 4 ) + hex_table[c2];
  174.         if ( value1 >= 256 )
  175.         pm_error( "syntax error" );
  176.         c1 = getc( stream );
  177.         c2 = getc( stream );
  178.         if ( c1 == EOF || c2 == EOF )
  179.         pm_error( "EOF / read error" );
  180.         value2 = ( hex_table[c1] << 4 ) + hex_table[c2];
  181.         if ( value2 >= 256 )
  182.         pm_error( "syntax error" );
  183.         *ptr++ = value2;
  184.         if ( ( ! padding ) || ( ( bytes + 2 ) % bytes_per_line ) )
  185.             *ptr++ = value1;
  186.         }
  187.     else
  188.     for ( bytes = 0, ptr = *dataP; bytes < raster_length; ++bytes )
  189.         {
  190.         /*
  191.         ** Skip until digit is found.
  192.         */
  193.         for ( ; ; )
  194.         {
  195.         c1 = getc( stream );
  196.         if ( c1 == EOF )
  197.             pm_error( "EOF / read error" );
  198.         value1 = hex_table[c1];
  199.         if ( value1 != 256 )
  200.             break;
  201.         }
  202.         /*
  203.         ** Loop on digits.
  204.         */
  205.         for ( ; ; )
  206.         {
  207.         c2 = getc( stream );
  208.         if ( c2 == EOF )
  209.             pm_error( "EOF / read error" );
  210.         value2 = hex_table[c2];
  211.         if ( value2 != 256 )
  212.             {
  213.             value1 = (value1 << 4) | value2;
  214.             if ( value1 >= 256 )
  215.             pm_error( "syntax error" );
  216.             }
  217.         else if ( c2 == 'x' || c2 == 'X' )
  218.             if ( value1 == 0 )
  219.             continue;
  220.             else pm_error( "syntax error" );
  221.             else break;
  222.             }
  223.         *ptr++ = value1;
  224.         }
  225.     }
  226.