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