bmtoa.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 * bmtoa - bitmap to ascii filter
31eaef79e5Smrg * Author:  Jim Fulton, MIT X Consortium
32eaef79e5Smrg */
33eaef79e5Smrg
34eaef79e5Smrg#ifdef HAVE_CONFIG_H
35eaef79e5Smrg# include "config.h"
36eaef79e5Smrg#endif
37eaef79e5Smrg
38eaef79e5Smrg#include <stdio.h>
39eaef79e5Smrg#include <X11/Xlib.h>
40eaef79e5Smrg#include <X11/Xutil.h>
41eaef79e5Smrg#include <X11/Xos.h>
42eaef79e5Smrg
43eaef79e5Smrg#include <X11/Xmu/Drawing.h>
44eaef79e5Smrg
45eaef79e5Smrg#include <stdlib.h>
46eaef79e5Smrg#include <unistd.h>
47eaef79e5Smrg#ifndef HAS_MKSTEMP
48eaef79e5Smrgextern char *mktemp();
49eaef79e5Smrg#endif
50eaef79e5Smrg
512b32c8f7Smrgstatic char *ProgramName;
52eaef79e5Smrg
53eaef79e5Smrgstatic void print_scanline (unsigned int width, unsigned int height,
54eaef79e5Smrg			    unsigned char *data, char *chars);
55eaef79e5Smrg
56eaef79e5Smrgstatic void
57eaef79e5Smrgusage (void)
58eaef79e5Smrg{
59eaef79e5Smrg    fprintf (stderr, "usage:  %s [-options ...] [filename]\n\n",
60eaef79e5Smrg	     ProgramName);
61eaef79e5Smrg    fprintf (stderr,
62eaef79e5Smrg	"where options include:\n");
63eaef79e5Smrg    fprintf (stderr,
64eaef79e5Smrg	"    -chars cc        chars to use for 0 and 1 bits, respectively\n");
65eaef79e5Smrg    fprintf (stderr, "\n");
66eaef79e5Smrg    exit (1);
67eaef79e5Smrg}
68eaef79e5Smrg
69eaef79e5Smrgstatic char *
70eaef79e5Smrgcopy_stdin (void)
71eaef79e5Smrg{
72eaef79e5Smrg#ifdef WIN32
73eaef79e5Smrg    static char tmpfilename[] = "/temp/bmtoa.XXXXXX";
74eaef79e5Smrg#else
75eaef79e5Smrg    static char tmpfilename[] = "/tmp/bmtoa.XXXXXX";
76eaef79e5Smrg#endif
77eaef79e5Smrg    char buf[BUFSIZ];
78eaef79e5Smrg    FILE *fp;
79eaef79e5Smrg    int nread, nwritten;
80eaef79e5Smrg
81eaef79e5Smrg#ifndef HAS_MKSTEMP
82eaef79e5Smrg    if (mktemp (tmpfilename) == NULL) {
83eaef79e5Smrg	fprintf (stderr,
84eaef79e5Smrg		 "%s:  unable to genererate temporary file name for stdin.\n",
85eaef79e5Smrg		 ProgramName);
86eaef79e5Smrg	exit (1);
87eaef79e5Smrg    }
88eaef79e5Smrg    fp = fopen (tmpfilename, "w");
89eaef79e5Smrg#else
90eaef79e5Smrg    int fd;
91eaef79e5Smrg
92eaef79e5Smrg    if ((fd = mkstemp(tmpfilename)) < 0) {
93eaef79e5Smrg	fprintf (stderr,
94eaef79e5Smrg		 "%s:  unable to genererate temporary file name for stdin.\n",
95eaef79e5Smrg		 ProgramName);
96eaef79e5Smrg	exit (1);
97eaef79e5Smrg    }
98eaef79e5Smrg    fp = fdopen(fd, "w");
99eaef79e5Smrg#endif
100eaef79e5Smrg    while (1) {
101eaef79e5Smrg	buf[0] = '\0';
102eaef79e5Smrg	nread = fread (buf, 1, sizeof buf, stdin);
103eaef79e5Smrg	if (nread <= 0) break;
104eaef79e5Smrg	nwritten = fwrite (buf, 1, nread, fp);
105eaef79e5Smrg	if (nwritten != nread) {
106eaef79e5Smrg	    fprintf (stderr,
107eaef79e5Smrg		     "%s:  error copying stdin to file (%d of %d chars)\n",
108eaef79e5Smrg		     ProgramName, nwritten, nread);
109eaef79e5Smrg	    (void) fclose (fp);
110eaef79e5Smrg	    (void) unlink (tmpfilename);
111eaef79e5Smrg	    exit (1);
112eaef79e5Smrg	}
113eaef79e5Smrg    }
114eaef79e5Smrg    (void) fclose (fp);
115eaef79e5Smrg    return tmpfilename;
116eaef79e5Smrg}
117eaef79e5Smrg
118eaef79e5Smrgint
119eaef79e5Smrgmain (int argc, char *argv[])
120eaef79e5Smrg{
121eaef79e5Smrg    char *filename = NULL;
122eaef79e5Smrg    int isstdin = 0;
123eaef79e5Smrg    char *chars = "-#";
124eaef79e5Smrg    int i;
125eaef79e5Smrg    unsigned int width, height;
126eaef79e5Smrg    unsigned char *data;
127eaef79e5Smrg    int x_hot, y_hot;
128eaef79e5Smrg    int status;
129eaef79e5Smrg
130eaef79e5Smrg    ProgramName = argv[0];
131eaef79e5Smrg
132eaef79e5Smrg    for (i = 1; i < argc; i++) {
133eaef79e5Smrg	char *arg = argv[i];
134eaef79e5Smrg
135eaef79e5Smrg	if (arg[0] == '-') {
136eaef79e5Smrg	    switch (arg[1]) {
137eaef79e5Smrg	      case '\0':
138eaef79e5Smrg		filename = NULL;
139eaef79e5Smrg		continue;
140eaef79e5Smrg	      case 'c':
141eaef79e5Smrg		if (++i >= argc) usage ();
142eaef79e5Smrg		chars = argv[i];
143eaef79e5Smrg		continue;
144eaef79e5Smrg	      default:
145eaef79e5Smrg		usage ();
146eaef79e5Smrg	    }
147eaef79e5Smrg	} else {
148eaef79e5Smrg	    filename = arg;
149eaef79e5Smrg	}
150eaef79e5Smrg    }
151eaef79e5Smrg
152eaef79e5Smrg    if (strlen (chars) != 2) {
153eaef79e5Smrg	fprintf (stderr,
154eaef79e5Smrg	 "%s:  bad character list \"%s\", must have exactly 2 characters\n",
155eaef79e5Smrg		 ProgramName, chars);
156eaef79e5Smrg	exit (1);
157eaef79e5Smrg    }
158eaef79e5Smrg
159eaef79e5Smrg    if (!filename) {
160eaef79e5Smrg	filename = copy_stdin ();
161eaef79e5Smrg	isstdin = 1;
162eaef79e5Smrg    }
163eaef79e5Smrg
164eaef79e5Smrg    status = XmuReadBitmapDataFromFile (filename, &width, &height, &data,
165eaef79e5Smrg					&x_hot, &y_hot);
166eaef79e5Smrg    if (isstdin) (void) unlink (filename);  /* don't need it anymore */
167eaef79e5Smrg    if (status != BitmapSuccess) {
168eaef79e5Smrg	fprintf (stderr, "%s:  unable to read bitmap from file \"%s\"\n",
169eaef79e5Smrg		 ProgramName, isstdin ? "(stdin)" : filename);
170eaef79e5Smrg	exit (1);
171eaef79e5Smrg    }
172eaef79e5Smrg
173eaef79e5Smrg    print_scanline (width, height, data, chars);
174eaef79e5Smrg    exit (0);
175eaef79e5Smrg}
176eaef79e5Smrg
177eaef79e5Smrgstatic void
178eaef79e5Smrgprint_scanline (unsigned int width,
179eaef79e5Smrg		unsigned int height,
180eaef79e5Smrg		unsigned char *data,
181eaef79e5Smrg		char *chars)
182eaef79e5Smrg{
183eaef79e5Smrg    char *scanline = (char *) malloc (width + 1);
184eaef79e5Smrg    unsigned char *dp = data;
185eaef79e5Smrg    int row, column;
186eaef79e5Smrg    static unsigned char masktable[] = {
187eaef79e5Smrg	0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
188eaef79e5Smrg    int padded = ((width & 7) != 0);
189eaef79e5Smrg
190eaef79e5Smrg    if (!scanline) {
191eaef79e5Smrg	fprintf (stderr, "%s:  unable to allocate %d bytes for scanline\n",
192eaef79e5Smrg		 ProgramName, width + 1);
193eaef79e5Smrg	exit (1);
194eaef79e5Smrg    }
195eaef79e5Smrg
196eaef79e5Smrg    for (row = 0; row < height; row++) {
197eaef79e5Smrg	for (column = 0; column < width; column++) {
198eaef79e5Smrg	    int i = (column & 7);
199eaef79e5Smrg
200eaef79e5Smrg	    if (*dp & masktable[i]) {
201eaef79e5Smrg		putchar (chars[1]);
202eaef79e5Smrg	    } else {
203eaef79e5Smrg		putchar (chars[0]);
204eaef79e5Smrg	    }
205eaef79e5Smrg
206eaef79e5Smrg	    if (i == 7) dp++;
207eaef79e5Smrg	}
208eaef79e5Smrg	putchar ('\n');
209eaef79e5Smrg	if (padded) dp++;
210eaef79e5Smrg    }
211eaef79e5Smrg    return;
212eaef79e5Smrg}
213eaef79e5Smrg
214