home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / clients / bitmap / atobm.c next >
Encoding:
C/C++ Source or Header  |  1991-02-17  |  6.6 KB  |  279 lines

  1. /*
  2.  * atobm - ascii to bitmap filter
  3.  *
  4.  * $XConsortium: atobm.c,v 1.1 91/02/18 10:49:58 dave Exp $
  5.  *
  6.  * Copyright 1988 Massachusetts Institute of Technology
  7.  *
  8.  * Permission to use, copy, modify, and distribute this software and its
  9.  * documentation for any purpose and without fee is hereby granted, provided
  10.  * that the above copyright notice appear in all copies and that both that
  11.  * copyright notice and this permission notice appear in supporting
  12.  * documentation, and that the name of M.I.T. not be used in advertising or
  13.  * publicity pertaining to distribution of the software without specific,
  14.  * written prior permission.  M.I.T. makes no representations about the
  15.  * suitability of this software for any purpose.  It is provided "as is"
  16.  * without express or implied warranty.
  17.  *
  18.  * Author:  Jim Fulton, MIT X Consortium
  19.  */
  20.  
  21. #include <stdio.h>
  22. #include <ctype.h>
  23. #include <X11/Xos.h>
  24.  
  25. extern char *malloc(), *calloc();
  26.  
  27. char *ProgramName;
  28.  
  29. static void usage ()
  30. {
  31.     fprintf (stderr, "usage:  %s [-options ...] [filename]\n\n",
  32.          ProgramName);
  33.     fprintf (stderr, 
  34.     "where options include:\n");
  35.     fprintf (stderr, 
  36.     "    -chars cc        chars to use for 0 and 1 bits, respectively\n");
  37.     fprintf (stderr, 
  38.     "    -name variable   name to use in bitmap file\n");
  39.     fprintf (stderr, 
  40.     "    -xhot number     x position of hotspot\n");
  41.     fprintf (stderr,
  42.     "    -yhot number     y position of hotspot\n");
  43.     fprintf (stderr, "\n");
  44.     exit (1);
  45. }
  46.  
  47.  
  48. char *cify_name (name)
  49.     char *name;
  50. {
  51.     int length = name ? strlen (name) : 0;
  52.     int i;
  53.  
  54.     for (i = 0; i < length; i++) {    /* strncpy (result, begin, length); */
  55.     char c = name[i];
  56.     if (!((isascii(c) && isalnum(c)) || c == '_')) name[i] = '_';
  57.     }
  58.     return name;
  59. }
  60.  
  61. char *StripName(name)
  62.   char *name;
  63. {
  64.   char *begin = rindex (name, '/');
  65.   char *end, *result;
  66.   int length;
  67.  
  68.   begin = (begin ? begin+1 : name);
  69.   end = index (begin, '.');    /* change to rindex to allow longer names */
  70.   length = (end ? (end - begin) : strlen (begin));
  71.   result = (char *) malloc (length + 1);
  72.   strncpy (result, begin, length);
  73.   result [length] = '\0';
  74.   return (result);
  75. }
  76.  
  77. main (argc, argv)
  78.     int argc;
  79.     char **argv;
  80. {
  81.     int i;
  82.     int xhot = -1, yhot = -1;
  83.     char *filename = NULL;
  84.     char *chars = "-#";
  85.     char *name = NULL;
  86.     FILE *fp;
  87.  
  88.     ProgramName = argv[0];
  89.  
  90.     for (i = 1; i < argc; i++) {
  91.     char *arg = argv[i];
  92.  
  93.     if (arg[0] == '-') {
  94.         switch (arg[1]) {
  95.           case '\0':
  96.         filename = NULL;
  97.         continue;
  98.           case 'c':
  99.         if (++i >= argc) usage ();
  100.         chars = argv[i];
  101.         continue;
  102.           case 'n':
  103.         if (++i >= argc) usage ();
  104.         name = argv[i];
  105.         continue;
  106.           case 'x':
  107.         if (++i >= argc) usage ();
  108.         xhot = atoi (argv[i]);
  109.         continue;
  110.           case 'y':
  111.         if (++i >= argc) usage ();
  112.         yhot = atoi (argv[i]);
  113.         continue;
  114.           default:
  115.         usage ();
  116.         }
  117.     } else {
  118.         filename = arg;
  119.     }
  120.     }
  121.  
  122.     if (strlen (chars) != 2) {
  123.     fprintf (stderr,
  124.      "%s:  bad character list \"%s\", must have exactly 2 characters\n",
  125.          ProgramName, chars);
  126.     exit (1);
  127.     }
  128.  
  129.     if (filename) {
  130.     fp = fopen (filename, "r");
  131.     if (!fp) {
  132.         fprintf (stderr, "%s:  unable to open file \"%s\".\n",
  133.              ProgramName, filename);
  134.         exit (1);
  135.     }
  136.     } else {
  137.     fp = stdin;
  138.     }
  139.  
  140.     if (!name) name = filename ? StripName (filename) : "";
  141.     cify_name (name);
  142.     doit (fp, filename, chars, xhot, yhot, name);
  143.  
  144.     if (filename) (void) fclose (fp);
  145.     exit (0);
  146. }
  147.  
  148.  
  149. doit (fp, filename, chars, xhot, yhot, name)
  150.     FILE *fp;
  151.     char *filename;
  152.     char *chars;
  153.     int xhot, yhot;
  154.     char *name;
  155. {
  156.     int i, j;
  157.     int last_character;
  158.     char buf[BUFSIZ];
  159.     char *cp, *newline;
  160.     int width = 0, height = 0;
  161.     int len;
  162.     int removespace = (((isascii(chars[0]) && isspace(chars[0])) ||
  163.             (isascii(chars[1]) && isspace(chars[1]))) ? 0 : 1);
  164.     int lineno = 0;
  165.     int bytes_per_scanline = 0;
  166.     struct _scan_list {
  167.     int allocated;
  168.     int used;
  169.     unsigned char *scanlines;
  170.     struct _scan_list *next;
  171.     } *head = NULL, *slist;
  172.     static unsigned char masktable[] = {
  173.     0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
  174.     int padded = 0;
  175.     
  176. #define NTOALLOC 16
  177. #define NewSList() \
  178.         slist = (struct _scan_list *) calloc (1, sizeof *slist); \
  179.         if (!slist) { \
  180.         fprintf (stderr, "%s:  unable to allocate scan list\n", \
  181.              ProgramName); \
  182.         return; \
  183.         } \
  184.         slist->allocated = NTOALLOC * bytes_per_scanline; \
  185.         slist->scanlines = (unsigned char *) calloc(slist->allocated, 1); \
  186.         if (!slist->scanlines) { \
  187.         fprintf (stderr, "%s:  unable to allocate char array\n", \
  188.              ProgramName); \
  189.         return; \
  190.         } \
  191.         slist->used = 0; \
  192.         slist->next = NULL; 
  193.  
  194.     while (1) {
  195.     buf[0] = '\0';
  196.     lineno++;
  197.     if (fgets (buf, sizeof buf, fp) == NULL) break;
  198.  
  199.     if (removespace) {
  200.         for (cp = buf; *cp && isascii(*cp) && isspace(*cp); cp++) ;
  201.     }
  202.     if (*cp == '\n' || !*cp) continue;  /* empty line */
  203.  
  204.     newline = index (cp, '\n');
  205.     if (!newline) {
  206.         fprintf (stderr, "%s:  line %d too long.\n",
  207.              ProgramName, lineno);
  208.         return;
  209.     }
  210.  
  211.     if (removespace) {
  212.         for (; --newline > cp && isascii(*newline) && isspace(*newline); );
  213.         newline++;
  214.     }
  215.  
  216.     if (newline == cp + 1) continue;
  217.  
  218.     *newline = '\0';
  219.     len = strlen (cp);
  220.  
  221.     if (width == 0) {
  222.         width = len;
  223.         padded = ((width & 7) != 0);
  224.         bytes_per_scanline = (len + 7) / 8;
  225.         NewSList ();
  226.         head = slist;
  227.     } else if (width != len) {
  228.         fprintf (stderr,
  229.              "%s:  line %d is %d characters wide instead of %d\n",
  230.              ProgramName, lineno, len, width);
  231.         return;
  232.     }
  233.  
  234.     if (slist->used + 1 >= slist->allocated) {
  235.         struct _scan_list *old = slist;
  236.         NewSList ();
  237.         old->next = slist;
  238.     }
  239.  
  240.     /* okay, parse the line and stick values into the scanline array */
  241.     for (i = 0; i < width; i++) {
  242.         int ind = (i & 7);
  243.         int on = 0;
  244.  
  245.         if (cp[i] == chars[1]) {
  246.         on = 1;
  247.         } else if (cp[i] != chars[0]) {
  248.         fprintf (stderr, "%s:  bad character '%c' on line %d\n",
  249.              ProgramName, cp[i], lineno);
  250.         }
  251.  
  252.         if (on) slist->scanlines[slist->used] |= masktable[ind];
  253.         if (ind == 7) slist->used++;
  254.     }
  255.     if (padded) slist->used++;
  256.     height++;
  257.     }
  258.  
  259.     printf ("#define %s_width %d\n", name, width);
  260.     printf ("#define %s_height %d\n", name, height);
  261.     if (xhot >= 0) printf ("#define %s_x_hot %d\n", name, xhot);
  262.     if (yhot >= 0) printf ("#define %s_y_hot %d\n", name, yhot);
  263.     printf ("\n");
  264.     printf ("static char %s_bits[] = {\n", name);
  265.  
  266.     j = 0;
  267.     last_character = height * bytes_per_scanline - 1;
  268.     for (slist = head; slist; slist = slist->next) {
  269.     for (i = 0; i < slist->used; i++) {
  270.         printf (" 0x%02x", slist->scanlines[i]);
  271.         if (j != last_character) putchar (',');
  272.         if ((j % 12) == 11) putchar ('\n');
  273.         j++;
  274.     }
  275.     }
  276.     printf (" };\n");
  277.     return;
  278. }
  279.