diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2006-08-19 03:12:28 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2006-08-19 03:12:28 +0000 |
commit | 1fd361a1ea06e44286c213ca1f814f49306fdc43 (patch) | |
tree | 64c8c96cf54d8718847339a403e5e67b922e8c3f /converter/pbm/xbmtopbm.c | |
download | netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.tar.gz netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.tar.xz netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.zip |
Create Subversion repository
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/pbm/xbmtopbm.c')
-rw-r--r-- | converter/pbm/xbmtopbm.c | 255 |
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. + + + + + +*/ |