bmtoa.c revision cbc4e2be
1/*
2
3Copyright 1988, 1993, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included
12in all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall
23not be used in advertising or otherwise to promote the sale, use or
24other dealings in this Software without prior written authorization
25from The Open Group.
26
27*/
28
29/*
30 * bmtoa - bitmap to ascii filter
31 * Author:  Jim Fulton, MIT X Consortium
32 */
33
34#ifdef HAVE_CONFIG_H
35# include "config.h"
36#endif
37
38#include <stdio.h>
39#include <X11/Xlib.h>
40#include <X11/Xutil.h>
41#include <X11/Xos.h>
42
43#include <X11/Xmu/Drawing.h>
44
45#include <stdlib.h>
46#include <unistd.h>
47#ifndef HAVE_MKSTEMP
48extern char *mktemp();
49#endif
50
51static char *ProgramName;
52
53static void print_scanline (unsigned int width, unsigned int height,
54			    unsigned const char *data, const char *chars);
55
56static void _X_NORETURN
57usage (void)
58{
59    fprintf (stderr, "usage:  %s [-options ...] [filename]\n\n%s\n",
60	     ProgramName,
61	"where options include:\n"
62	"    -chars cc        chars to use for 0 and 1 bits, respectively\n");
63    exit (1);
64}
65
66static char *
67copy_stdin (void)
68{
69#ifdef WIN32
70    static char tmpfilename[] = "/temp/bmtoa.XXXXXX";
71#else
72    static char tmpfilename[] = "/tmp/bmtoa.XXXXXX";
73#endif
74    char buf[BUFSIZ];
75    FILE *fp = NULL;
76    int nread, nwritten;
77
78#ifndef HAVE_MKSTEMP
79    if (mktemp (tmpfilename) != NULL)
80	fp = fopen (tmpfilename, "w");
81#else
82    int fd;
83    if ((fd = mkstemp(tmpfilename)) >= 0)
84	fp = fdopen(fd, "w");
85#endif
86    if (fp == NULL) {
87	fprintf (stderr,
88		 "%s:  unable to generate temporary file for stdin.\n",
89		 ProgramName);
90	exit (1);
91    }
92    while (1) {
93	buf[0] = '\0';
94	nread = fread (buf, 1, sizeof buf, stdin);
95	if (nread <= 0) break;
96	nwritten = fwrite (buf, 1, nread, fp);
97	if (nwritten != nread) {
98	    fprintf (stderr,
99		     "%s:  error copying stdin to file (%d of %d chars)\n",
100		     ProgramName, nwritten, nread);
101	    (void) fclose (fp);
102	    (void) unlink (tmpfilename);
103	    exit (1);
104	}
105    }
106    (void) fclose (fp);
107    return tmpfilename;
108}
109
110int
111main (int argc, char *argv[])
112{
113    const char *filename = NULL;
114    int isstdin = 0;
115    const char *chars = "-#";
116    int i;
117    unsigned int width, height;
118    unsigned char *data;
119    int x_hot, y_hot;
120    int status;
121
122    ProgramName = argv[0];
123
124    for (i = 1; i < argc; i++) {
125	const char *arg = argv[i];
126
127	if (arg[0] == '-') {
128	    switch (arg[1]) {
129	      case '\0':
130		filename = NULL;
131		continue;
132	      case 'c':
133		if (++i >= argc) usage ();
134		chars = argv[i];
135		continue;
136	      default:
137		usage ();
138	    }
139	} else {
140	    filename = arg;
141	}
142    }
143
144    if (strlen (chars) != 2) {
145	fprintf (stderr,
146	 "%s:  bad character list \"%s\", must have exactly 2 characters\n",
147		 ProgramName, chars);
148	exit (1);
149    }
150
151    if (!filename) {
152	filename = copy_stdin ();
153	isstdin = 1;
154    }
155
156    status = XmuReadBitmapDataFromFile (filename, &width, &height, &data,
157					&x_hot, &y_hot);
158    if (isstdin) (void) unlink (filename);  /* don't need it anymore */
159    if (status != BitmapSuccess) {
160	fprintf (stderr, "%s:  unable to read bitmap from file \"%s\"\n",
161		 ProgramName, isstdin ? "(stdin)" : filename);
162	exit (1);
163    }
164
165    print_scanline (width, height, data, chars);
166    exit (0);
167}
168
169static void
170print_scanline (unsigned int width,
171		unsigned int height,
172		unsigned const char *data,
173		const char *chars)
174{
175    unsigned const char *dp = data;
176    int row, column;
177    static unsigned const char masktable[] = {
178	0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
179    int padded = ((width & 7) != 0);
180
181    for (row = 0; row < height; row++) {
182	for (column = 0; column < width; column++) {
183	    int i = (column & 7);
184
185	    if (*dp & masktable[i]) {
186		putchar (chars[1]);
187	    } else {
188		putchar (chars[0]);
189	    }
190
191	    if (i == 7) dp++;
192	}
193	putchar ('\n');
194	if (padded) dp++;
195    }
196    return;
197}
198
199