home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1399 < prev    next >
Internet Message Format  |  1990-12-28  |  12KB

  1. From: ian@csuchico.edu (Ian Kluft)
  2. Newsgroups: alt.sources
  3. Subject: bitresize - filter to resize X11 bitmaps
  4. Message-ID: <1990Jun01.061009.11438@csuchico.edu>
  5. Date: 1 Jun 90 06:10:09 GMT
  6.  
  7. Have you ever wanted to resize an X11 bitmap?  There may be several reasons
  8. why.
  9.  
  10. Reasons to resize a bitmap
  11. --------------------------
  12. * resizing a bitmap after you realize it isn't big enough for what you wanted
  13. * removing a border from a bitmap (i.e. converted from another graphics format)
  14. * preparation for editing an old bitmap
  15.  
  16. This problem is solved with bitresize.  It makes a copy of a bitmap in any
  17. size.  
  18.  
  19. Usage: bitresize width height [ input-file [ output-file ] ]
  20.  
  21. How to install bitresize
  22. ------------------------
  23.    1) unarchive the shar file
  24.    2) type "make"
  25.    3) read the manual page by typing
  26.       nroff -man bitresize.1 | more
  27.  
  28. How bitresize works
  29. -------------------
  30. While the idea is fairly simple, bitresize is a little complicated because it
  31. has to deal with the syntax of an X11 bitmap file, which is basically a subset
  32. of C.  Therefore, yacc and lex were used to quickly build a parser for the
  33. X11 bitmap format.  Therefore, to understand the source code, it helps to
  34. understand yacc and lex.  (However, you can easily get a general idea about
  35. it by looking at the sources.)
  36.  
  37. This is a simple data flow diagram of bitresize.
  38.  
  39. input file --(text)-->  scanner --(tokens)--> parser  --(text)--> output file
  40.             scan.l              bitmap.y
  41.  
  42. Most of the work is done in bitmap.y.  Additional C functions are appended to
  43. the end of bitmap.y because, well, this was just a one-evening project and that
  44. was one way to put it together quickly. :-)
  45.  
  46. [You'll notice that this intro was mostly taken verbatim from the README file.]
  47.  
  48. --------------------------------- cut here ---------------------------------
  49. #
  50. # This is a shell archive.  Remove anything before this line,
  51. # then unpack it by saving it in a file and typing "sh file".
  52. #
  53. # Wrapped by Ian Kluft <ian@csuchico.edu> on Thu May 31 22:49:56 1990
  54. #
  55. # This archive contains:
  56. #    README        bitresize.1    Makefile    bitmap.y    
  57. #    scan.l        
  58. #
  59.  
  60. LANG=""; export LANG
  61. PATH=/bin:/usr/bin:$PATH; export PATH
  62.  
  63. echo x - README
  64. cat >README <<'@EOF'
  65. A quick introduction to the "Bitresize" program
  66. by Ian Kluft
  67. California State University, Chico
  68.  
  69. Have you ever wanted to resize an X11 bitmap?  There may be several reasons
  70. why.  This program was made in one evening (as the sparse documentation
  71. attests to) after one bitmap was made just a little too small.  It should
  72. have had a larger border in order to look good as an X11 background.
  73.  
  74. Reasons to resize a bitmap
  75. --------------------------
  76. * resizing a bitmap after you realize it isn't big enough for what you wanted
  77. * removing a border from a bitmap (i.e. converted from another graphics format)
  78. * preparation for editing an old bitmap
  79.  
  80. This problem is solved with bitresize.  It makes a copy of a bitmap
  81. in any size.  
  82.  
  83. Usage: bitresize width height [ input-file [ output-file ] ]
  84.  
  85. How to install bitresize
  86. ------------------------
  87.    1) unarchive the shar file
  88.    2) type "make"
  89.    3) read the manual page by typing
  90.       nroff -man bitresize.1 | more
  91.  
  92. How bitresize works
  93. -------------------
  94. While the idea is fairly simple, bitresize is a little complicated because it
  95. has to deal with the syntax of an X11 bitmap file, which is basically a subset
  96. of C.  Therefore, yacc and lex were used to quickly build a parser for the
  97. X11 bitmap format.  Therefore, to understand the source code, it helps to
  98. understand yacc and lex.  (However, you can easily get a general idea about
  99. it by looking at the sources.)
  100.  
  101. This is a simple data flow diagram of bitresize.
  102.  
  103. input file --(text)-->  scanner --(tokens)--> parser  --(text)--> output file
  104.             scan.l              bitmap.y
  105.  
  106. Most of the work is done in bitmap.y.  Additional C functions are appended to
  107. the end of bitmap.y because, well, this was just a one-evening project and that
  108. was one way to put it together quickly.
  109. @EOF
  110.  
  111. chmod 600 README
  112.  
  113. echo x - bitresize.1
  114. cat >bitresize.1 <<'@EOF'
  115. .TH BITRESIZE 1 
  116. .SH NAME
  117. bitresize \- resize an X11 bitmap
  118. .SH SYNOPSIS
  119. .B "bitresize width height"
  120. [
  121. .B input-file
  122. [
  123. .B output-file
  124. ] ]
  125. .SH DESCRIPTION
  126. .I Bitresize\^
  127. is a filter program that can transform an
  128. X11 bitmap file to an identical bitmap of a different size.
  129. If the size (in pixels wide and high) is too
  130. small for the previous bitmap to fit into,
  131. .I bitresize\^
  132. will retain as much of the upper left corner as possible.
  133. .PP
  134. This feature can be used to clip borders off of bitmaps.  If the
  135. .I bitmap(1)\^
  136. editor (by MIT and included with X11) is used to move the
  137. image to the upper left corner,
  138. .I bitresize\^
  139. can be used to make a smaller copy of the bitmap without
  140. the border.
  141. .PP
  142. .I Bitresize\^
  143. can also be used to increase the size of a bitmap for
  144. addition of more details.
  145. .PP
  146. For example,
  147. .PP
  148. .RS
  149. bitresize 128 64 <old.bitmap.file >new.bitmap.file
  150. .RE
  151. .PP
  152. resizes the X11 bitmap "old.bitmap.file"
  153. into a bitmap called "new.bitmap.file" which will be
  154. 128 pixels wide by 64 pixels high, regardless
  155. of the size of the old bitmap.  Also
  156. .PP
  157. .RS
  158. bitresize 128 64 old.bitmap.file new.bitmap.file
  159. .RE
  160. .PP
  161. does the same thing except that I/O is done directly
  162. to the files without using the shell's I/O redirection
  163. .PP
  164. If no input file is given,
  165. or if the argument
  166. .B \-
  167. is encountered,
  168. .I bitresize\^
  169. reads from the standard
  170. input file.  This is the default action and the same works with
  171. the standard output.
  172. .PP
  173. Note that no changes are made to the input file by
  174. .I bitresize\^ .
  175. .SH WARNING
  176. As with any program,
  177. .I bitresize\^
  178. will not function correctly if the input and output
  179. files are the same.  In such a situation, the input
  180. bitmap file will probably be destroyed.
  181. As usual, prevention of this error is left to the user.
  182. .SH RETURN VALUE
  183. Exit values are:
  184. .RS 3
  185. .TP 8
  186. .B 0
  187. Successful completion.
  188. .PD 0
  189. .TP
  190. .B 1
  191. Error condition occured.
  192. .RE
  193. .PD
  194. .SH AUTHOR
  195. .I Bitresize\^
  196. was written by Ian Kluft at California State University, Chico.
  197. .SH SEE ALSO
  198. bitmap(1)
  199. @EOF
  200.  
  201. chmod 600 bitresize.1
  202.  
  203. echo x - Makefile
  204. cat >Makefile <<'@EOF'
  205. #
  206. #    Makefile for bitresize
  207. #    by Ian Kluft
  208. #    California State University, Chico
  209. #    5/90
  210. #
  211. YFLAGS=-dv
  212. LFLAGS=
  213. CFLAGS=-O
  214.  
  215. SRCS=bitmap.y scan.l
  216. OBJS=bitmap.o scan.o
  217. SHARFILES=README bitresize.1 Makefile $(SRCS)
  218.  
  219. bitresize: $(OBJS)
  220.     cc $(OBJS) -ll -ly -o bitresize
  221.  
  222. shar:
  223.     shar $(SHARFILES) > bitresize.shar
  224. @EOF
  225.  
  226. chmod 600 Makefile
  227.  
  228. echo x - bitmap.y
  229. cat >bitmap.y <<'@EOF'
  230. /*
  231.  *
  232.  *    X11 bitmap resizer
  233.  *    by Ian Kluft
  234.  *    California State University, Chico
  235.  *    5/90
  236.  *
  237.  */
  238.  
  239. %union {
  240.     char    *string;
  241.     int    value;
  242. }
  243.  
  244. %{
  245. #include    <stdio.h>
  246. #include    <malloc.h>
  247.  
  248. #define        PIXTOBYTE(pix)    ((int)(((pix)+7)/8))
  249.  
  250. int        width,
  251.         height,
  252.         old_width,
  253.         old_height;
  254.  
  255. char        *width_name,
  256.         *height_name,
  257.         *bitmap_name,
  258.         *bits;        /* dynamic 2-D array w/ bytes from bitmap */
  259.  
  260. extern void    allocate_bitmap (),
  261.         put_byte (), 
  262.         output_bitmap ();
  263. %}
  264.  
  265. %token <string>    ID 
  266. %token <value>    DEFINE INTEGER HEX STATIC CHAR
  267.  
  268. %type <value>    width height allocate bitmap bytes
  269.  
  270. %start bitmap_file
  271. %%
  272. bitmap_file
  273.     : width height allocate bitmap
  274.     ;
  275.  
  276. width
  277.     : '#' DEFINE ID INTEGER
  278.     {
  279.         width_name = $3;
  280.         old_width = $4;
  281.     }
  282.     ;
  283.  
  284. height
  285.     : '#' DEFINE ID INTEGER
  286.     {
  287.         height_name = $3;
  288.         old_height = $4;
  289.     }
  290.     ;
  291.  
  292. allocate
  293.     : /* nothing */
  294.     {
  295.         allocate_bitmap ( width, height );
  296.     }
  297.     ;
  298.  
  299. bitmap
  300.     : STATIC CHAR ID '[' ']' '=' '{' bytes '}' ';'
  301.     {
  302.         bitmap_name = $3;
  303.     }
  304.     ;
  305.  
  306. bytes
  307.     : bytes ',' HEX
  308.     {
  309.         put_byte ( $3 );
  310.         $$ = $1 + 1;
  311.     }
  312.     | HEX
  313.     {
  314.         put_byte ( $1 );
  315.         $$ = 1;
  316.     }
  317.     ;
  318. %%
  319. main ( argc, argv )
  320. int    argc;
  321. char    *argv[];
  322. {
  323.     if ( argc < 3 )
  324.     {
  325.         fprintf ( stderr,
  326.             "usage: %s width height [input_file [output_file]]\n",
  327.             argv[ 0 ] );
  328.         exit ( 1 );
  329.     }
  330.  
  331.     /* get new width & height from command line */
  332.     width = atoi ( argv[ 1 ] );
  333.     if ( width <= 0 )
  334.     {
  335.         fprintf ( stderr, "%s: width must be positive\n", argv[ 0 ] );
  336.         exit ( 1 );
  337.     }
  338.     height = atoi ( argv[ 2 ] );
  339.     if ( height <= 0 )
  340.     {
  341.         fprintf ( stderr, "%s: height must be positive\n", argv[ 0 ] );
  342.         exit ( 1 );
  343.     }
  344.  
  345.     /* perform file redirection if requested */
  346.     if ( argc >= 4 && strcmp ( argv[ 3 ], "-" ) != NULL )
  347.         if (( freopen ( argv[ 3 ], "r", stdin )) == NULL )
  348.         {
  349.             perror ( argv[ 0 ] );
  350.             fprintf ( stderr, "cannot open %s for reading\n",
  351.                 argv[ 3 ] );
  352.             exit ( 1 );
  353.         }
  354.     if ( argc >= 5 && strcmp ( argv[ 4 ], "-" ) != NULL )
  355.         if (( freopen ( argv[ 4 ], "w", stdout )) == NULL )
  356.         {
  357.             perror ( argv[ 0 ] );
  358.             fprintf ( stderr, "cannot open %s for writing\n",
  359.                 argv[ 4 ] );
  360.             exit ( 1 );
  361.         }
  362.  
  363.     /* parse through the bitmap */
  364.     yyparse ();
  365.  
  366.     /* print the output */
  367.     output_bitmap ();
  368. }
  369.  
  370. void allocate_bitmap ( w, h )
  371. int    w, h;
  372. {
  373.     if (( bits = calloc ( h * PIXTOBYTE ( w ), 1 )) == NULL )
  374.     {
  375.         fprintf ( stderr, "memory allocation error\n" );
  376.         exit ( 1 );
  377.     }
  378. }
  379.  
  380. void put_byte ( b )
  381. int    b;
  382. {
  383.     static int    loc = 0;
  384.  
  385.     int        over,
  386.             down;
  387.  
  388.     /* compute position */
  389.     down = ( int ) loc / PIXTOBYTE ( old_width );
  390.     over = ( int ) loc % PIXTOBYTE ( old_width );
  391.  
  392.     /* if it fits in the new bitmap size, copy it */
  393.     if ( down < height && over < PIXTOBYTE ( width )) 
  394.         *(( char * ) bits + ( over + down * PIXTOBYTE ( width ))) =
  395.             ( char ) b;
  396.     loc++;
  397. }
  398.  
  399. void output_bitmap ()
  400. {
  401.     int    loc;
  402.  
  403.     printf ( "#define %s %d\n", width_name, width );
  404.     printf ( "#define %s %d\n", height_name, height );
  405.     printf ( "static char %s[] = {", bitmap_name );
  406.  
  407.     for ( loc = 0; loc < PIXTOBYTE ( width ) * height; loc++ )
  408.     {
  409.         static char    digits[] = "0123456789abcdef",
  410.                 hex[ 3 ] = "xx";
  411.  
  412.         /* formatting */
  413.         if ( loc % 12 == 0 )
  414.             printf ( "\n   " );
  415.         else
  416.             printf ( " " );
  417.  
  418.         /* form and print hex string */
  419.         hex[ 0 ] = digits[ (( *( bits + loc )) & 240 ) >> 4 ];
  420.         hex[ 1 ] = digits[ ( *( bits + loc )) & 15 ];
  421.         printf ( "0x%2s", hex );
  422.  
  423.         /* print a comma if another byte will follow */
  424.         if ( loc < PIXTOBYTE ( width ) * height - 1 )
  425.             printf ( "," );
  426.     }
  427.     printf ( "};\n" );
  428. }
  429. @EOF
  430.  
  431. chmod 600 bitmap.y
  432.  
  433. echo x - scan.l
  434. cat >scan.l <<'@EOF'
  435. %{
  436. /*
  437.  *
  438.  *    scanner for bitmap parser
  439.  *    by Ian Kluft
  440.  *    California State University, Chico
  441.  *    5/90
  442.  *
  443.  */
  444.  
  445. #include "y.tab.h"
  446. #include <stdio.h>
  447. #include <string.h>
  448.  
  449. #ifdef    DEBUG
  450. #  define    DEBUG_OUTS(fmt,str)    printf(fmt,str)
  451. #  define    DEBUG_OUTC(out)        putchar(out)
  452. #else !DEBUG
  453. #  define    DEBUG_OUTS(fmt,str)
  454. #  define    DEBUG_OUTC(out)
  455. #endif DEBUG
  456. %}
  457. %%
  458. [ \t\n]    { DEBUG_OUTS( "%s", yytext ); }  /* skip whitespace */ 
  459. "0x"[0-9a-fA-F]+ {
  460.     yylval.value = strtoul ( yytext + 2, ( char ** ) NULL, 16 );
  461.     DEBUG_OUTS( "%s", yytext );
  462.     return ( HEX ); }
  463. [0-9]+ {
  464.     yylval.value = atoi ( yytext );
  465.     DEBUG_OUTS( "%s", yytext );
  466.     return ( INTEGER ); }
  467. "define" { DEBUG_OUTS( "%s", yytext ); return ( DEFINE ); }
  468. "static" { DEBUG_OUTS( "%s", yytext ); return ( STATIC ); }
  469. "char"    { DEBUG_OUTS( "%s", yytext ); return ( CHAR ); }
  470. [a-zA-Z_][a-zA-Z0-9_]* {
  471.     yylval.string = strdup ( yytext );
  472.     DEBUG_OUTS( "%s", yytext );
  473.     return ( ID ); }
  474. "/*"    {    /* skip comments */
  475.     int    done,
  476.         c;
  477.  
  478.     DEBUG_OUTS ( "%s", yytext );
  479.     done = 0;
  480.     while ( ! done )
  481.     {
  482.         c = input (); DEBUG_OUTC ( c );
  483.         if ( c == '*' )
  484.         {
  485.             c = input (); DEBUG_OUTC ( c );
  486.             done = ( c == '/' );
  487.         }
  488.     }
  489. }
  490. .    { DEBUG_OUTS( "%s", yytext ); return ( yytext[0] ); }  /* everything else */
  491. %%
  492. @EOF
  493.  
  494. chmod 600 scan.l
  495.  
  496. exit 0
  497.  
  498. --------------------------- cut out signature here ---------------------------
  499.  
  500. --
  501. Ian Kluft               ----------------------------- # Sometimes all it takes
  502. grad student, CSU Chico          \ |--*--| /          # to make someone a real
  503. member ACM, UPE, AOPA     C - 172  /\___/\  Skyhawk   # flying enthusiast is...
  504. PP-SEL                            o   o   o           #      one flight
  505.