home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume2 / pbm / Part2 / xbmtopbm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-07  |  4.0 KB  |  200 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 <stdio.h>
  14. #include <sys/types.h>
  15. #include "pbm.h"
  16.  
  17. main( argc, argv )
  18. int argc;
  19. char *argv[];
  20.     {
  21.     FILE *ifd;
  22.     bit **bits;
  23.     int rows, cols, row, col, charcount;
  24.     char *data, mask;
  25.  
  26.     if ( argc > 2 )
  27.     {
  28.     fprintf( stderr, "usage: %s [bitmapfile]\n", argv[0] );
  29.     exit( 1 );
  30.     }
  31.     
  32.     if ( argc == 2 )
  33.     {
  34.     ifd = fopen( argv[1], "r" );
  35.     if ( ifd == NULL )
  36.         {
  37.         fprintf( stderr, "%s: can't open.\n", argv[1] );
  38.         exit( 1 );
  39.         }
  40.     }
  41.     else
  42.     ifd = stdin;
  43.  
  44.     if ( ReadBitmapFile( ifd, &cols, &rows, &data ) < 0 )
  45.     {
  46.     fprintf( stderr, "%s: can't load.\n", argv[1] );
  47.     exit( 1 );
  48.     }
  49.  
  50.     if ( ifd != stdin )
  51.     fclose( ifd );
  52.  
  53.     bits = pbm_allocarray( cols, rows );
  54.  
  55.     for ( row = 0; row < rows; row++ )
  56.     {
  57.     charcount = 0;
  58.     mask = 1;
  59.     for ( col = 0; col < cols; col++ )
  60.         {
  61.         if ( charcount >= 8 )
  62.         {
  63.         data++;
  64.         charcount = 0;
  65.         mask = 1;
  66.         }
  67.         bits[row][col] = ( *data & mask ) ? 1 : 0;
  68.         charcount++;
  69.         mask = mask << 1;
  70.         }
  71.     data++;
  72.     }
  73.  
  74.     pbm_writepbm( stdout, bits, cols, rows );
  75.  
  76.     exit( 0 );
  77.     }
  78.  
  79.  
  80. #ifdef    OS_SYSV
  81. #include <string.h>
  82. #else    OS_SYSV
  83. #include <strings.h>
  84. #endif    OS_SYSV
  85.  
  86. #define MAX_LINE 81
  87.  
  88. int
  89. ReadBitmapFile( stream, widthP, heightP, dataP )
  90. FILE *stream;
  91. int *widthP, *heightP;
  92. char **dataP;
  93.     {
  94.     char line[MAX_LINE], name_and_type[MAX_LINE];
  95.     char *ptr, *t;
  96.     int bytes, bytes_per_line, value, version10p, raster_length, padding;
  97.  
  98.     *widthP = *heightP = -1;
  99.  
  100.     for ( ; ; )
  101.     {
  102.     if ( ! fgets( line, MAX_LINE, stream ) )
  103.         break;
  104.     if ( strlen( line ) == MAX_LINE - 1 )
  105.         {
  106.         fprintf( stderr, "Line too long.\n" );
  107.         return ( -1 );
  108.         }
  109.  
  110.     if (sscanf(line, "#define %s %d", name_and_type, &value) == 2)
  111.         {
  112. #ifdef    OS_SYSV
  113.         if ( ! (t = strrchr( name_and_type, '_' )) )
  114. #else    OS_SYSV
  115.         if ( ! (t = rindex( name_and_type, '_' )) )
  116. #endif    OS_SYSV
  117.         t = name_and_type;
  118.         else
  119.         t++;
  120.         if ( ! strcmp( "width", t ) )
  121.         *widthP = value;
  122.         if ( ! strcmp( "height", t ) )
  123.         *heightP = value;
  124.         continue;
  125.         }
  126.     
  127.     if ( sscanf( line, "static short %s = {", name_and_type ) == 1 )
  128.         {
  129.         version10p = 1;
  130.         break;
  131.         }
  132.     else if ( sscanf( line, "static char %s = {", name_and_type ) == 1 )
  133.         {
  134.         version10p = 0;
  135.         break;
  136.         }
  137.     else
  138.         continue;
  139.     }
  140.  
  141. #ifdef    OS_SYSV
  142.     if ( ! (t = strrchr( name_and_type, '_' )) )
  143. #else    OS_SYSV
  144.     if ( ! (t = rindex( name_and_type, '_' )) )
  145. #endif    OS_SYSV
  146.     t = name_and_type;
  147.     else
  148.     t++;
  149.     
  150.     if ( *widthP == -1 )
  151.     {
  152.     fprintf( stderr, "Invalid width.\n" );
  153.     return ( -1 );
  154.     }
  155.     if ( *heightP == -1 )
  156.     {
  157.     fprintf( stderr, "Invalid height.\n" );
  158.     return ( -1 );
  159.     }
  160.  
  161.     padding = 0;
  162.     if ( ((*widthP % 16) >= 1) && ((*widthP % 16) <= 8) && version10p )
  163.     padding = 1;
  164.  
  165.     bytes_per_line = (*widthP+7)/8 + padding;
  166.     
  167.     raster_length =  bytes_per_line * *heightP;
  168.     *dataP = (char *) malloc( raster_length );
  169.     if ( ! *dataP )
  170.     {
  171.     fprintf( stderr, "Not enough memory.\n" );
  172.     return ( -1 );
  173.     }
  174.  
  175.     if ( version10p )
  176.     for ( bytes = 0, ptr = *dataP; bytes < raster_length; bytes += 2 )
  177.         {
  178.         if ( fscanf( stream, " 0x%x%*[,}]%*[ \n]", &value ) != 1 )
  179.         {
  180.         fprintf( stderr, "Error scanning bits item.\n" );
  181.         return ( -1 );
  182.         }
  183.         *(ptr++) = value & 0xff;
  184.         if ( (! padding) || ((bytes+2) % bytes_per_line) )
  185.         *(ptr++) = value >> 8;
  186.         }
  187.     else
  188.         for ( bytes = 0, ptr = *dataP; bytes < raster_length; bytes++ )
  189.         {
  190.         if ( fscanf( stream, " 0x%x%*[,}]%*[ \n]", &value ) != 1 )
  191.             {
  192.             fprintf( stderr, "Error scanning bits item.\n" );
  193.             return ( -1 );
  194.             }
  195.         *(ptr++) = value;
  196.         }
  197.  
  198.     return ( 0 );
  199.     }
  200.