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