about summary refs log tree commit diff
path: root/converter/pbm/xbmtopbm.c
diff options
context:
space:
mode:
Diffstat (limited to 'converter/pbm/xbmtopbm.c')
-rw-r--r--converter/pbm/xbmtopbm.c255
1 files changed, 255 insertions, 0 deletions
diff --git a/converter/pbm/xbmtopbm.c b/converter/pbm/xbmtopbm.c
new file mode 100644
index 00000000..7779a9b5
--- /dev/null
+++ b/converter/pbm/xbmtopbm.c
@@ -0,0 +1,255 @@
+/* xbmtopbm.c - read an X bitmap file and produce a portable bitmap
+**
+** Copyright (C) 1988 by Jef Poskanzer.
+**
+** Permission to use, copy, modify, and distribute this software and its
+** documentation for any purpose and without fee is hereby granted, provided
+** that the above copyright notice appear in all copies and that both that
+** copyright notice and this permission notice appear in supporting
+** documentation.  This software is provided "as is" without express or
+** implied warranty.
+*/
+
+#include <string.h>
+
+#include "nstring.h"
+#include "pbm.h"
+
+#define TRUE 1
+#define FALSE 0
+
+static void ReadBitmapFile ARGS(( FILE* stream, int* widthP, int* heightP, char** dataP ));
+
+int
+main( argc, argv )
+    int argc;
+    char* argv[];
+    {
+    FILE* ifp;
+    bit* bitrow;
+    register bit* bP;
+    int rows, cols, row, col, charcount;
+    char* data;
+    char mask;
+
+    pbm_init( &argc, argv );
+
+    if ( argc > 2 )
+        pm_usage( "[bitmapfile]" );
+    
+    if ( argc == 2 )
+        ifp = pm_openr( argv[1] );
+    else
+        ifp = stdin;
+
+    ReadBitmapFile( ifp, &cols, &rows, &data );
+
+    pm_close( ifp );
+
+    pbm_writepbminit( stdout, cols, rows, 0 );
+    bitrow = pbm_allocrow( cols );
+
+    for ( row = 0; row < rows; ++row )
+        {
+        charcount = 0;
+        mask = 1;
+        for ( col = 0, bP = bitrow; col < cols; ++col, ++bP )
+            {
+            if ( charcount >= 8 )
+                {
+                ++data;
+                charcount = 0;
+                mask = 1;
+                }
+            *bP = ( *data & mask ) ? PBM_BLACK : PBM_WHITE;
+            ++charcount;
+            mask = mask << 1;
+            }
+        ++data;
+        pbm_writepbmrow( stdout, bitrow, cols, 0 );
+        }
+
+    pm_close( stdout );
+    exit( 0 );
+    }
+
+#define MAX_LINE 500
+
+static void
+ReadBitmapFile( stream, widthP, heightP, dataP )
+     FILE* stream;
+     int* widthP;
+     int* heightP;
+     char** dataP;
+{
+  char line[MAX_LINE], name_and_type[MAX_LINE];
+  char* ptr;
+  char* t;
+  int version10, raster_length, v;
+  register int bytes, bytes_per_line, padding;
+  register int c1, c2, value1, value2;
+  int hex_table[256];
+  int found_declaration;
+  /* In scanning through the bitmap file, we have found the first
+     line of the C declaration of the array (the "static char ..."
+     or whatever line)
+     */
+  int eof;
+  /* We've encountered end of file while searching file */
+
+  *widthP = *heightP = -1;
+
+  found_declaration = FALSE;    /* Haven't found it yet; haven't even looked*/
+  eof = FALSE;                  /* Haven't encountered end of file yet */
+
+  while (!found_declaration && !eof) {
+    if ( fgets( line, MAX_LINE, stream ) == NULL )
+      eof = TRUE;
+    else {
+      if ( strlen( line ) == MAX_LINE - 1 )
+        pm_error( "line too long" );
+
+      if ( sscanf( line, "#define %s %d", name_and_type, &v ) == 2 ) {
+        if ( ( t = strrchr( name_and_type, '_' ) ) == NULL )
+          t = name_and_type;
+        else
+          ++t;
+        if ( STREQ( "width", t ) )
+          *widthP = v;
+        else if ( STREQ( "height", t ) )
+          *heightP = v;
+        continue;
+      }
+        
+      if ( sscanf( line, "static short %s = {", name_and_type ) == 1 ) {
+        version10 = TRUE;
+        found_declaration = TRUE;
+      }
+      else if ( sscanf( line, "static char %s = {", name_and_type ) == 1 ) {
+        version10 = FALSE;
+        found_declaration = TRUE;
+      }
+      else if (sscanf(line, 
+                      "static unsigned char %s = {", name_and_type ) == 1 ) {
+        version10 = FALSE;
+        found_declaration = TRUE;
+      }
+    }
+  }
+ 
+  if (!found_declaration) 
+    pm_error("Unable to find a line in the file containing the start "
+             "of C array declaration (\"static char\" or whatever)");
+
+  if ( *widthP == -1 )
+    pm_error( "invalid width" );
+  if ( *heightP == -1 )
+    pm_error( "invalid height" );
+
+  padding = 0;
+  if ( ((*widthP % 16) >= 1) && ((*widthP % 16) <= 8) && version10 )
+    padding = 1;
+
+  bytes_per_line = (*widthP+7)/8 + padding;
+    
+  raster_length =  bytes_per_line * *heightP;
+  *dataP = (char*) malloc( raster_length );
+  if ( *dataP == (char*) 0 )
+    pm_error( "out of memory" );
+
+  /* Initialize hex_table. */
+  for ( c1 = 0; c1 < 256; ++c1 )
+    hex_table[c1] = 256;
+  hex_table['0'] = 0;
+  hex_table['1'] = 1;
+  hex_table['2'] = 2;
+  hex_table['3'] = 3;
+  hex_table['4'] = 4;
+  hex_table['5'] = 5;
+  hex_table['6'] = 6;
+  hex_table['7'] = 7;
+  hex_table['8'] = 8;
+  hex_table['9'] = 9;
+  hex_table['A'] = 10;
+  hex_table['B'] = 11;
+  hex_table['C'] = 12;
+  hex_table['D'] = 13;
+  hex_table['E'] = 14;
+  hex_table['F'] = 15;
+  hex_table['a'] = 10;
+  hex_table['b'] = 11;
+  hex_table['c'] = 12;
+  hex_table['d'] = 13;
+  hex_table['e'] = 14;
+  hex_table['f'] = 15;
+
+  if ( version10 )
+    for ( bytes = 0, ptr = *dataP; bytes < raster_length; bytes += 2 ) {
+      while ( ( c1 = getc( stream ) ) != 'x' )
+        if ( c1 == EOF )
+          pm_error( "EOF / read error" );
+      c1 = getc( stream );
+      c2 = getc( stream );
+      if ( c1 == EOF || c2 == EOF )
+        pm_error( "EOF / read error" );
+      value1 = ( hex_table[c1] << 4 ) + hex_table[c2];
+      if ( value1 >= 256 )
+        pm_error( "syntax error" );
+      c1 = getc( stream );
+      c2 = getc( stream );
+      if ( c1 == EOF || c2 == EOF )
+        pm_error( "EOF / read error" );
+      value2 = ( hex_table[c1] << 4 ) + hex_table[c2];
+      if ( value2 >= 256 )
+        pm_error( "syntax error" );
+      *ptr++ = value2;
+      if ( ( ! padding ) || ( ( bytes + 2 ) % bytes_per_line ) )
+        *ptr++ = value1;
+    }
+  else
+    for ( bytes = 0, ptr = *dataP; bytes < raster_length; ++bytes ) {
+      /*
+       ** Skip until digit is found.
+       */
+      for ( ; ; )
+        {
+          c1 = getc( stream );
+          if ( c1 == EOF )
+            pm_error( "EOF / read error" );
+          value1 = hex_table[c1];
+          if ( value1 != 256 )
+            break;
+        }
+      /*
+       ** Loop on digits.
+       */
+      for ( ; ; ) {
+        c2 = getc( stream );
+        if ( c2 == EOF )
+          pm_error( "EOF / read error" );
+        value2 = hex_table[c2];
+        if ( value2 != 256 ) {
+          value1 = (value1 << 4) | value2;
+          if ( value1 >= 256 )
+            pm_error( "syntax error" );
+        }
+        else if ( c2 == 'x' || c2 == 'X' )
+          if ( value1 == 0 )
+            continue;
+          else pm_error( "syntax error" );
+        else break;
+      }
+      *ptr++ = value1;
+    }
+}
+
+
+/*  CHANGE HISTORY:
+
+  99.09.08 bryanh    Recognize "static unsigned char" declaration.
+
+
+
+
+
+*/