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