bmtoa.c revision d1a7ce7b
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) {
134		    fprintf(stderr, "%s: -chars requires an argument\n",
135			    ProgramName);
136		    usage ();
137		}
138		chars = argv[i];
139		continue;
140	      default:
141		fprintf(stderr, "%s: unrecognized option '%s'\n",
142			ProgramName, argv[i]);
143		usage ();
144	    }
145	} else {
146	    filename = arg;
147	}
148    }
149
150    if (strlen (chars) != 2) {
151	fprintf (stderr,
152	 "%s:  bad character list \"%s\", must have exactly 2 characters\n",
153		 ProgramName, chars);
154	exit (1);
155    }
156
157    if (!filename) {
158	filename = copy_stdin ();
159	isstdin = 1;
160    }
161
162    status = XmuReadBitmapDataFromFile (filename, &width, &height, &data,
163					&x_hot, &y_hot);
164    if (isstdin) (void) unlink (filename);  /* don't need it anymore */
165    if (status != BitmapSuccess) {
166	fprintf (stderr, "%s:  unable to read bitmap from file \"%s\"\n",
167		 ProgramName, isstdin ? "(stdin)" : filename);
168	exit (1);
169    }
170
171    print_scanline (width, height, data, chars);
172    exit (0);
173}
174
175static void
176print_scanline (unsigned int width,
177		unsigned int height,
178		unsigned const char *data,
179		const char *chars)
180{
181    unsigned const char *dp = data;
182    int row, column;
183    static unsigned const char masktable[] = {
184	0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
185    int padded = ((width & 7) != 0);
186
187    for (row = 0; row < height; row++) {
188	for (column = 0; column < width; column++) {
189	    int i = (column & 7);
190
191	    if (*dp & masktable[i]) {
192		putchar (chars[1]);
193	    } else {
194		putchar (chars[0]);
195	    }
196
197	    if (i == 7) dp++;
198	}
199	putchar ('\n');
200	if (padded) dp++;
201    }
202    return;
203}
204
205