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