ian@csuchico.edu (Ian Kluft) (06/01/90)
Have you ever wanted to resize an X11 bitmap? There may be several reasons why. Reasons to resize a bitmap -------------------------- * resizing a bitmap after you realize it isn't big enough for what you wanted * removing a border from a bitmap (i.e. converted from another graphics format) * preparation for editing an old bitmap This problem is solved with bitresize. It makes a copy of a bitmap in any size. Usage: bitresize width height [ input-file [ output-file ] ] How to install bitresize ------------------------ 1) unarchive the shar file 2) type "make" 3) read the manual page by typing nroff -man bitresize.1 | more How bitresize works ------------------- While the idea is fairly simple, bitresize is a little complicated because it has to deal with the syntax of an X11 bitmap file, which is basically a subset of C. Therefore, yacc and lex were used to quickly build a parser for the X11 bitmap format. Therefore, to understand the source code, it helps to understand yacc and lex. (However, you can easily get a general idea about it by looking at the sources.) This is a simple data flow diagram of bitresize. input file --(text)--> scanner --(tokens)--> parser --(text)--> output file scan.l bitmap.y Most of the work is done in bitmap.y. Additional C functions are appended to the end of bitmap.y because, well, this was just a one-evening project and that was one way to put it together quickly. :-) [You'll notice that this intro was mostly taken verbatim from the README file.] --------------------------------- cut here --------------------------------- # # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by Ian Kluft <ian@csuchico.edu> on Thu May 31 22:49:56 1990 # # This archive contains: # README bitresize.1 Makefile bitmap.y # scan.l # LANG=""; export LANG PATH=/bin:/usr/bin:$PATH; export PATH echo x - README cat >README <<'@EOF' A quick introduction to the "Bitresize" program by Ian Kluft California State University, Chico Have you ever wanted to resize an X11 bitmap? There may be several reasons why. This program was made in one evening (as the sparse documentation attests to) after one bitmap was made just a little too small. It should have had a larger border in order to look good as an X11 background. Reasons to resize a bitmap -------------------------- * resizing a bitmap after you realize it isn't big enough for what you wanted * removing a border from a bitmap (i.e. converted from another graphics format) * preparation for editing an old bitmap This problem is solved with bitresize. It makes a copy of a bitmap in any size. Usage: bitresize width height [ input-file [ output-file ] ] How to install bitresize ------------------------ 1) unarchive the shar file 2) type "make" 3) read the manual page by typing nroff -man bitresize.1 | more How bitresize works ------------------- While the idea is fairly simple, bitresize is a little complicated because it has to deal with the syntax of an X11 bitmap file, which is basically a subset of C. Therefore, yacc and lex were used to quickly build a parser for the X11 bitmap format. Therefore, to understand the source code, it helps to understand yacc and lex. (However, you can easily get a general idea about it by looking at the sources.) This is a simple data flow diagram of bitresize. input file --(text)--> scanner --(tokens)--> parser --(text)--> output file scan.l bitmap.y Most of the work is done in bitmap.y. Additional C functions are appended to the end of bitmap.y because, well, this was just a one-evening project and that was one way to put it together quickly. @EOF chmod 600 README echo x - bitresize.1 cat >bitresize.1 <<'@EOF' .TH BITRESIZE 1 .SH NAME bitresize \- resize an X11 bitmap .SH SYNOPSIS .B "bitresize width height" [ .B input-file [ .B output-file ] ] .SH DESCRIPTION .I Bitresize\^ is a filter program that can transform an X11 bitmap file to an identical bitmap of a different size. If the size (in pixels wide and high) is too small for the previous bitmap to fit into, .I bitresize\^ will retain as much of the upper left corner as possible. .PP This feature can be used to clip borders off of bitmaps. If the .I bitmap(1)\^ editor (by MIT and included with X11) is used to move the image to the upper left corner, .I bitresize\^ can be used to make a smaller copy of the bitmap without the border. .PP .I Bitresize\^ can also be used to increase the size of a bitmap for addition of more details. .PP For example, .PP .RS bitresize 128 64 <old.bitmap.file >new.bitmap.file .RE .PP resizes the X11 bitmap "old.bitmap.file" into a bitmap called "new.bitmap.file" which will be 128 pixels wide by 64 pixels high, regardless of the size of the old bitmap. Also .PP .RS bitresize 128 64 old.bitmap.file new.bitmap.file .RE .PP does the same thing except that I/O is done directly to the files without using the shell's I/O redirection .PP If no input file is given, or if the argument .B \- is encountered, .I bitresize\^ reads from the standard input file. This is the default action and the same works with the standard output. .PP Note that no changes are made to the input file by .I bitresize\^ . .SH WARNING As with any program, .I bitresize\^ will not function correctly if the input and output files are the same. In such a situation, the input bitmap file will probably be destroyed. As usual, prevention of this error is left to the user. .SH RETURN VALUE Exit values are: .RS 3 .TP 8 .B 0 Successful completion. .PD 0 .TP .B 1 Error condition occured. .RE .PD .SH AUTHOR .I Bitresize\^ was written by Ian Kluft at California State University, Chico. .SH SEE ALSO bitmap(1) @EOF chmod 600 bitresize.1 echo x - Makefile cat >Makefile <<'@EOF' # # Makefile for bitresize # by Ian Kluft # California State University, Chico # 5/90 # YFLAGS=-dv LFLAGS= CFLAGS=-O SRCS=bitmap.y scan.l OBJS=bitmap.o scan.o SHARFILES=README bitresize.1 Makefile $(SRCS) bitresize: $(OBJS) cc $(OBJS) -ll -ly -o bitresize shar: shar $(SHARFILES) > bitresize.shar @EOF chmod 600 Makefile echo x - bitmap.y cat >bitmap.y <<'@EOF' /* * * X11 bitmap resizer * by Ian Kluft * California State University, Chico * 5/90 * */ %union { char *string; int value; } %{ #include <stdio.h> #include <malloc.h> #define PIXTOBYTE(pix) ((int)(((pix)+7)/8)) int width, height, old_width, old_height; char *width_name, *height_name, *bitmap_name, *bits; /* dynamic 2-D array w/ bytes from bitmap */ extern void allocate_bitmap (), put_byte (), output_bitmap (); %} %token <string> ID %token <value> DEFINE INTEGER HEX STATIC CHAR %type <value> width height allocate bitmap bytes %start bitmap_file %% bitmap_file : width height allocate bitmap ; width : '#' DEFINE ID INTEGER { width_name = $3; old_width = $4; } ; height : '#' DEFINE ID INTEGER { height_name = $3; old_height = $4; } ; allocate : /* nothing */ { allocate_bitmap ( width, height ); } ; bitmap : STATIC CHAR ID '[' ']' '=' '{' bytes '}' ';' { bitmap_name = $3; } ; bytes : bytes ',' HEX { put_byte ( $3 ); $$ = $1 + 1; } | HEX { put_byte ( $1 ); $$ = 1; } ; %% main ( argc, argv ) int argc; char *argv[]; { if ( argc < 3 ) { fprintf ( stderr, "usage: %s width height [input_file [output_file]]\n", argv[ 0 ] ); exit ( 1 ); } /* get new width & height from command line */ width = atoi ( argv[ 1 ] ); if ( width <= 0 ) { fprintf ( stderr, "%s: width must be positive\n", argv[ 0 ] ); exit ( 1 ); } height = atoi ( argv[ 2 ] ); if ( height <= 0 ) { fprintf ( stderr, "%s: height must be positive\n", argv[ 0 ] ); exit ( 1 ); } /* perform file redirection if requested */ if ( argc >= 4 && strcmp ( argv[ 3 ], "-" ) != NULL ) if (( freopen ( argv[ 3 ], "r", stdin )) == NULL ) { perror ( argv[ 0 ] ); fprintf ( stderr, "cannot open %s for reading\n", argv[ 3 ] ); exit ( 1 ); } if ( argc >= 5 && strcmp ( argv[ 4 ], "-" ) != NULL ) if (( freopen ( argv[ 4 ], "w", stdout )) == NULL ) { perror ( argv[ 0 ] ); fprintf ( stderr, "cannot open %s for writing\n", argv[ 4 ] ); exit ( 1 ); } /* parse through the bitmap */ yyparse (); /* print the output */ output_bitmap (); } void allocate_bitmap ( w, h ) int w, h; { if (( bits = calloc ( h * PIXTOBYTE ( w ), 1 )) == NULL ) { fprintf ( stderr, "memory allocation error\n" ); exit ( 1 ); } } void put_byte ( b ) int b; { static int loc = 0; int over, down; /* compute position */ down = ( int ) loc / PIXTOBYTE ( old_width ); over = ( int ) loc % PIXTOBYTE ( old_width ); /* if it fits in the new bitmap size, copy it */ if ( down < height && over < PIXTOBYTE ( width )) *(( char * ) bits + ( over + down * PIXTOBYTE ( width ))) = ( char ) b; loc++; } void output_bitmap () { int loc; printf ( "#define %s %d\n", width_name, width ); printf ( "#define %s %d\n", height_name, height ); printf ( "static char %s[] = {", bitmap_name ); for ( loc = 0; loc < PIXTOBYTE ( width ) * height; loc++ ) { static char digits[] = "0123456789abcdef", hex[ 3 ] = "xx"; /* formatting */ if ( loc % 12 == 0 ) printf ( "\n " ); else printf ( " " ); /* form and print hex string */ hex[ 0 ] = digits[ (( *( bits + loc )) & 240 ) >> 4 ]; hex[ 1 ] = digits[ ( *( bits + loc )) & 15 ]; printf ( "0x%2s", hex ); /* print a comma if another byte will follow */ if ( loc < PIXTOBYTE ( width ) * height - 1 ) printf ( "," ); } printf ( "};\n" ); } @EOF chmod 600 bitmap.y echo x - scan.l cat >scan.l <<'@EOF' %{ /* * * scanner for bitmap parser * by Ian Kluft * California State University, Chico * 5/90 * */ #include "y.tab.h" #include <stdio.h> #include <string.h> #ifdef DEBUG # define DEBUG_OUTS(fmt,str) printf(fmt,str) # define DEBUG_OUTC(out) putchar(out) #else !DEBUG # define DEBUG_OUTS(fmt,str) # define DEBUG_OUTC(out) #endif DEBUG %} %% [ \t\n] { DEBUG_OUTS( "%s", yytext ); } /* skip whitespace */ "0x"[0-9a-fA-F]+ { yylval.value = strtoul ( yytext + 2, ( char ** ) NULL, 16 ); DEBUG_OUTS( "%s", yytext ); return ( HEX ); } [0-9]+ { yylval.value = atoi ( yytext ); DEBUG_OUTS( "%s", yytext ); return ( INTEGER ); } "define" { DEBUG_OUTS( "%s", yytext ); return ( DEFINE ); } "static" { DEBUG_OUTS( "%s", yytext ); return ( STATIC ); } "char" { DEBUG_OUTS( "%s", yytext ); return ( CHAR ); } [a-zA-Z_][a-zA-Z0-9_]* { yylval.string = strdup ( yytext ); DEBUG_OUTS( "%s", yytext ); return ( ID ); } "/*" { /* skip comments */ int done, c; DEBUG_OUTS ( "%s", yytext ); done = 0; while ( ! done ) { c = input (); DEBUG_OUTC ( c ); if ( c == '*' ) { c = input (); DEBUG_OUTC ( c ); done = ( c == '/' ); } } } . { DEBUG_OUTS( "%s", yytext ); return ( yytext[0] ); } /* everything else */ %% @EOF chmod 600 scan.l exit 0 --------------------------- cut out signature here --------------------------- -- Ian Kluft ----------------------------- # Sometimes all it takes grad student, CSU Chico \ |--*--| / # to make someone a real member ACM, UPE, AOPA C - 172 /\___/\ Skyhawk # flying enthusiast is... PP-SEL o o o # one flight