atobm.c revision 2b32c8f7
1eaef79e5Smrg/* 2eaef79e5Smrg 3eaef79e5SmrgCopyright 1988, 1993, 1998 The Open Group 4eaef79e5Smrg 5eaef79e5SmrgPermission to use, copy, modify, distribute, and sell this software and its 6eaef79e5Smrgdocumentation for any purpose is hereby granted without fee, provided that 7eaef79e5Smrgthe above copyright notice appear in all copies and that both that 8eaef79e5Smrgcopyright notice and this permission notice appear in supporting 9eaef79e5Smrgdocumentation. 10eaef79e5Smrg 11eaef79e5SmrgThe above copyright notice and this permission notice shall be included 12eaef79e5Smrgin all copies or substantial portions of the Software. 13eaef79e5Smrg 14eaef79e5SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15eaef79e5SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16eaef79e5SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17eaef79e5SmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 18eaef79e5SmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19eaef79e5SmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20eaef79e5SmrgOTHER DEALINGS IN THE SOFTWARE. 21eaef79e5Smrg 22eaef79e5SmrgExcept as contained in this notice, the name of The Open Group shall 23eaef79e5Smrgnot be used in advertising or otherwise to promote the sale, use or 24eaef79e5Smrgother dealings in this Software without prior written authorization 25eaef79e5Smrgfrom The Open Group. 26eaef79e5Smrg 27eaef79e5Smrg*/ 28eaef79e5Smrg 29eaef79e5Smrg/* 30eaef79e5Smrg * atobm - ascii to bitmap filter 31eaef79e5Smrg * Author: Jim Fulton, MIT X Consortium 32eaef79e5Smrg */ 33eaef79e5Smrg 34eaef79e5Smrg#include <stdio.h> 35eaef79e5Smrg#include <ctype.h> 36eaef79e5Smrg#include <X11/Xos.h> 37eaef79e5Smrg#include <stdlib.h> 38eaef79e5Smrg 392b32c8f7Smrgstatic char *ProgramName; 40eaef79e5Smrg 41eaef79e5Smrgstatic void doit(FILE *fp, char *filename, char *chars, 42eaef79e5Smrg int xhot, int yhot, char *name); 43eaef79e5Smrg 44eaef79e5Smrgstatic void 45eaef79e5Smrgusage (void) 46eaef79e5Smrg{ 47eaef79e5Smrg fprintf (stderr, "usage: %s [-options ...] [filename]\n\n", 48eaef79e5Smrg ProgramName); 49eaef79e5Smrg fprintf (stderr, 50eaef79e5Smrg "where options include:\n"); 51eaef79e5Smrg fprintf (stderr, 52eaef79e5Smrg " -chars cc chars to use for 0 and 1 bits, respectively\n"); 53eaef79e5Smrg fprintf (stderr, 54eaef79e5Smrg " -name variable name to use in bitmap file\n"); 55eaef79e5Smrg fprintf (stderr, 56eaef79e5Smrg " -xhot number x position of hotspot\n"); 57eaef79e5Smrg fprintf (stderr, 58eaef79e5Smrg " -yhot number y position of hotspot\n"); 59eaef79e5Smrg fprintf (stderr, "\n"); 60eaef79e5Smrg exit (1); 61eaef79e5Smrg} 62eaef79e5Smrg 63eaef79e5Smrg 64eaef79e5Smrgstatic char * 65eaef79e5Smrgcify_name (char *name) 66eaef79e5Smrg{ 67eaef79e5Smrg int length = name ? strlen (name) : 0; 68eaef79e5Smrg int i; 69eaef79e5Smrg 70eaef79e5Smrg for (i = 0; i < length; i++) { /* strncpy (result, begin, length); */ 71eaef79e5Smrg char c = name[i]; 72eaef79e5Smrg if (!((isascii(c) && isalnum(c)) || c == '_')) name[i] = '_'; 73eaef79e5Smrg } 74eaef79e5Smrg return name; 75eaef79e5Smrg} 76eaef79e5Smrg 77eaef79e5Smrgstatic char * 78eaef79e5SmrgStripName(char *name) 79eaef79e5Smrg{ 80eaef79e5Smrg char *begin = strrchr(name, '/'); 81eaef79e5Smrg char *end, *result; 82eaef79e5Smrg int length; 83eaef79e5Smrg 84eaef79e5Smrg begin = (begin ? begin+1 : name); 85eaef79e5Smrg end = strchr(begin, '.'); /* change to strrchr to allow longer names */ 86eaef79e5Smrg length = (end ? (end - begin) : strlen (begin)); 87eaef79e5Smrg result = (char *) malloc (length + 1); 88eaef79e5Smrg strncpy (result, begin, length); 89eaef79e5Smrg result [length] = '\0'; 90eaef79e5Smrg return (result); 91eaef79e5Smrg} 92eaef79e5Smrg 93eaef79e5Smrgint 94eaef79e5Smrgmain (int argc, char *argv[]) 95eaef79e5Smrg{ 96eaef79e5Smrg int i; 97eaef79e5Smrg int xhot = -1, yhot = -1; 98eaef79e5Smrg char *filename = NULL; 99eaef79e5Smrg char *chars = "-#"; 100eaef79e5Smrg char *name = NULL; 101eaef79e5Smrg FILE *fp; 102eaef79e5Smrg 103eaef79e5Smrg ProgramName = argv[0]; 104eaef79e5Smrg 105eaef79e5Smrg for (i = 1; i < argc; i++) { 106eaef79e5Smrg char *arg = argv[i]; 107eaef79e5Smrg 108eaef79e5Smrg if (arg[0] == '-') { 109eaef79e5Smrg switch (arg[1]) { 110eaef79e5Smrg case '\0': 111eaef79e5Smrg filename = NULL; 112eaef79e5Smrg continue; 113eaef79e5Smrg case 'c': 114eaef79e5Smrg if (++i >= argc) usage (); 115eaef79e5Smrg chars = argv[i]; 116eaef79e5Smrg continue; 117eaef79e5Smrg case 'n': 118eaef79e5Smrg if (++i >= argc) usage (); 119eaef79e5Smrg name = argv[i]; 120eaef79e5Smrg continue; 121eaef79e5Smrg case 'x': 122eaef79e5Smrg if (++i >= argc) usage (); 123eaef79e5Smrg xhot = atoi (argv[i]); 124eaef79e5Smrg continue; 125eaef79e5Smrg case 'y': 126eaef79e5Smrg if (++i >= argc) usage (); 127eaef79e5Smrg yhot = atoi (argv[i]); 128eaef79e5Smrg continue; 129eaef79e5Smrg default: 130eaef79e5Smrg usage (); 131eaef79e5Smrg } 132eaef79e5Smrg } else { 133eaef79e5Smrg filename = arg; 134eaef79e5Smrg } 135eaef79e5Smrg } 136eaef79e5Smrg 137eaef79e5Smrg if (strlen (chars) != 2) { 138eaef79e5Smrg fprintf (stderr, 139eaef79e5Smrg "%s: bad character list \"%s\", must have exactly 2 characters\n", 140eaef79e5Smrg ProgramName, chars); 141eaef79e5Smrg exit (1); 142eaef79e5Smrg } 143eaef79e5Smrg 144eaef79e5Smrg if (filename) { 145eaef79e5Smrg fp = fopen (filename, "r"); 146eaef79e5Smrg if (!fp) { 147eaef79e5Smrg fprintf (stderr, "%s: unable to open file \"%s\".\n", 148eaef79e5Smrg ProgramName, filename); 149eaef79e5Smrg exit (1); 150eaef79e5Smrg } 151eaef79e5Smrg } else { 152eaef79e5Smrg fp = stdin; 153eaef79e5Smrg } 154eaef79e5Smrg 155eaef79e5Smrg if (!name) name = filename ? StripName (filename) : ""; 156eaef79e5Smrg cify_name (name); 157eaef79e5Smrg doit (fp, filename, chars, xhot, yhot, name); 158eaef79e5Smrg 159eaef79e5Smrg if (filename) (void) fclose (fp); 160eaef79e5Smrg exit (0); 161eaef79e5Smrg} 162eaef79e5Smrg 163eaef79e5Smrg 164eaef79e5Smrgstatic void 165eaef79e5Smrgdoit (FILE *fp, 166eaef79e5Smrg char *filename, 167eaef79e5Smrg char *chars, 168eaef79e5Smrg int xhot, int yhot, 169eaef79e5Smrg char *name) 170eaef79e5Smrg{ 171eaef79e5Smrg int i, j; 172eaef79e5Smrg int last_character; 173eaef79e5Smrg char buf[BUFSIZ]; 174eaef79e5Smrg char *cp, *newline; 175eaef79e5Smrg int width = 0, height = 0; 176eaef79e5Smrg int len; 177eaef79e5Smrg int removespace = (((isascii(chars[0]) && isspace(chars[0])) || 178eaef79e5Smrg (isascii(chars[1]) && isspace(chars[1]))) ? 0 : 1); 179eaef79e5Smrg int lineno = 0; 180eaef79e5Smrg int bytes_per_scanline = 0; 181eaef79e5Smrg struct _scan_list { 182eaef79e5Smrg int allocated; 183eaef79e5Smrg int used; 184eaef79e5Smrg unsigned char *scanlines; 185eaef79e5Smrg struct _scan_list *next; 186eaef79e5Smrg } *head = NULL, *slist = NULL; 187eaef79e5Smrg static unsigned char masktable[] = { 188eaef79e5Smrg 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; 189eaef79e5Smrg int padded = 0; 190eaef79e5Smrg 191eaef79e5Smrg#define NTOALLOC 16 192eaef79e5Smrg#define NewSList() \ 193eaef79e5Smrg slist = (struct _scan_list *) calloc (1, sizeof *slist); \ 194eaef79e5Smrg if (!slist) { \ 195eaef79e5Smrg fprintf (stderr, "%s: unable to allocate scan list\n", \ 196eaef79e5Smrg ProgramName); \ 197eaef79e5Smrg return; \ 198eaef79e5Smrg } \ 199eaef79e5Smrg slist->allocated = NTOALLOC * bytes_per_scanline; \ 200eaef79e5Smrg slist->scanlines = (unsigned char *) calloc(slist->allocated, 1); \ 201eaef79e5Smrg if (!slist->scanlines) { \ 202eaef79e5Smrg fprintf (stderr, "%s: unable to allocate char array\n", \ 203eaef79e5Smrg ProgramName); \ 204eaef79e5Smrg return; \ 205eaef79e5Smrg } \ 206eaef79e5Smrg slist->used = 0; \ 207eaef79e5Smrg slist->next = NULL; 208eaef79e5Smrg 209eaef79e5Smrg while (1) { 210eaef79e5Smrg buf[0] = '\0'; 211eaef79e5Smrg lineno++; 212eaef79e5Smrg if (fgets (buf, sizeof buf, fp) == NULL) break; 213eaef79e5Smrg 214eaef79e5Smrg cp = buf; 215eaef79e5Smrg if (removespace) { 216eaef79e5Smrg for (cp = buf; *cp && isascii(*cp) && isspace(*cp); cp++) ; 217eaef79e5Smrg } 218eaef79e5Smrg if (*cp == '\n' || !*cp) continue; /* empty line */ 219eaef79e5Smrg 220eaef79e5Smrg newline = strchr(cp, '\n'); 221eaef79e5Smrg if (!newline) { 222eaef79e5Smrg fprintf (stderr, "%s: line %d too long.\n", 223eaef79e5Smrg ProgramName, lineno); 224eaef79e5Smrg return; 225eaef79e5Smrg } 226eaef79e5Smrg 227eaef79e5Smrg if (removespace) { 228eaef79e5Smrg for (; --newline > cp && isascii(*newline) && isspace(*newline); ); 229eaef79e5Smrg newline++; 230eaef79e5Smrg } 231eaef79e5Smrg 232eaef79e5Smrg if (newline == cp + 1) continue; 233eaef79e5Smrg 234eaef79e5Smrg *newline = '\0'; 235eaef79e5Smrg len = strlen (cp); 236eaef79e5Smrg 237eaef79e5Smrg if (width == 0) { 238eaef79e5Smrg width = len; 239eaef79e5Smrg padded = ((width & 7) != 0); 240eaef79e5Smrg bytes_per_scanline = (len + 7) / 8; 241eaef79e5Smrg NewSList (); 242eaef79e5Smrg head = slist; 243eaef79e5Smrg } else if (width != len) { 244eaef79e5Smrg fprintf (stderr, 245eaef79e5Smrg "%s: line %d is %d characters wide instead of %d\n", 246eaef79e5Smrg ProgramName, lineno, len, width); 247eaef79e5Smrg return; 248eaef79e5Smrg } 249eaef79e5Smrg 250eaef79e5Smrg if (slist->used + 1 >= slist->allocated) { 251eaef79e5Smrg struct _scan_list *old = slist; 252eaef79e5Smrg NewSList (); 253eaef79e5Smrg old->next = slist; 254eaef79e5Smrg } 255eaef79e5Smrg 256eaef79e5Smrg /* okay, parse the line and stick values into the scanline array */ 257eaef79e5Smrg for (i = 0; i < width; i++) { 258eaef79e5Smrg int ind = (i & 7); 259eaef79e5Smrg int on = 0; 260eaef79e5Smrg 261eaef79e5Smrg if (cp[i] == chars[1]) { 262eaef79e5Smrg on = 1; 263eaef79e5Smrg } else if (cp[i] != chars[0]) { 264eaef79e5Smrg fprintf (stderr, "%s: bad character '%c' on line %d\n", 265eaef79e5Smrg ProgramName, cp[i], lineno); 266eaef79e5Smrg } 267eaef79e5Smrg 268eaef79e5Smrg if (on) slist->scanlines[slist->used] |= masktable[ind]; 269eaef79e5Smrg if (ind == 7) slist->used++; 270eaef79e5Smrg } 271eaef79e5Smrg if (padded) slist->used++; 272eaef79e5Smrg height++; 273eaef79e5Smrg } 274eaef79e5Smrg 275eaef79e5Smrg printf ("#define %s_width %d\n", name, width); 276eaef79e5Smrg printf ("#define %s_height %d\n", name, height); 277eaef79e5Smrg if (xhot >= 0) printf ("#define %s_x_hot %d\n", name, xhot); 278eaef79e5Smrg if (yhot >= 0) printf ("#define %s_y_hot %d\n", name, yhot); 279eaef79e5Smrg printf ("\n"); 280eaef79e5Smrg printf ("static unsigned char %s_bits[] = {\n", name); 281eaef79e5Smrg 282eaef79e5Smrg j = 0; 283eaef79e5Smrg last_character = height * bytes_per_scanline - 1; 284eaef79e5Smrg for (slist = head; slist; slist = slist->next) { 285eaef79e5Smrg for (i = 0; i < slist->used; i++) { 286eaef79e5Smrg printf (" 0x%02x", slist->scanlines[i]); 287eaef79e5Smrg if (j != last_character) putchar (','); 288eaef79e5Smrg if ((j % 12) == 11) putchar ('\n'); 289eaef79e5Smrg j++; 290eaef79e5Smrg } 291eaef79e5Smrg } 292eaef79e5Smrg printf (" };\n"); 293eaef79e5Smrg return; 294eaef79e5Smrg} 295