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> 47cbc4e2beSmrg#ifndef HAVE_MKSTEMP 48eaef79e5Smrgextern char *mktemp(); 49eaef79e5Smrg#endif 50eaef79e5Smrg 512b32c8f7Smrgstatic char *ProgramName; 52eaef79e5Smrg 53cbc4e2beSmrgstatic void print_scanline (unsigned int width, unsigned int height, 54cbc4e2beSmrg unsigned const char *data, const char *chars); 55eaef79e5Smrg 56cbc4e2beSmrgstatic void _X_NORETURN 57433d0511Smrgusage (int exitval) 58eaef79e5Smrg{ 59cbc4e2beSmrg fprintf (stderr, "usage: %s [-options ...] [filename]\n\n%s\n", 60cbc4e2beSmrg ProgramName, 61cbc4e2beSmrg "where options include:\n" 62433d0511Smrg " -chars cc chars to use for 0 and 1 bits, respectively\n" 63433d0511Smrg " -help print this usage message\n" 64433d0511Smrg " -version print version information\n" 65433d0511Smrg ); 66433d0511Smrg exit (exitval); 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]; 78cbc4e2beSmrg FILE *fp = NULL; 79eaef79e5Smrg int nread, nwritten; 80eaef79e5Smrg 81cbc4e2beSmrg#ifndef HAVE_MKSTEMP 82cbc4e2beSmrg if (mktemp (tmpfilename) != NULL) 83cbc4e2beSmrg fp = fopen (tmpfilename, "w"); 84eaef79e5Smrg#else 85eaef79e5Smrg int fd; 86cbc4e2beSmrg if ((fd = mkstemp(tmpfilename)) >= 0) 87cbc4e2beSmrg fp = fdopen(fd, "w"); 88cbc4e2beSmrg#endif 89cbc4e2beSmrg if (fp == NULL) { 90eaef79e5Smrg fprintf (stderr, 91cbc4e2beSmrg "%s: unable to generate temporary file for stdin.\n", 92eaef79e5Smrg ProgramName); 93eaef79e5Smrg exit (1); 94eaef79e5Smrg } 95eaef79e5Smrg while (1) { 96eaef79e5Smrg buf[0] = '\0'; 97eaef79e5Smrg nread = fread (buf, 1, sizeof buf, stdin); 98eaef79e5Smrg if (nread <= 0) break; 99eaef79e5Smrg nwritten = fwrite (buf, 1, nread, fp); 100eaef79e5Smrg if (nwritten != nread) { 101eaef79e5Smrg fprintf (stderr, 102eaef79e5Smrg "%s: error copying stdin to file (%d of %d chars)\n", 103eaef79e5Smrg ProgramName, nwritten, nread); 104eaef79e5Smrg (void) fclose (fp); 105eaef79e5Smrg (void) unlink (tmpfilename); 106eaef79e5Smrg exit (1); 107eaef79e5Smrg } 108eaef79e5Smrg } 109eaef79e5Smrg (void) fclose (fp); 110eaef79e5Smrg return tmpfilename; 111eaef79e5Smrg} 112eaef79e5Smrg 113eaef79e5Smrgint 114cbc4e2beSmrgmain (int argc, char *argv[]) 115eaef79e5Smrg{ 116cbc4e2beSmrg const char *filename = NULL; 117eaef79e5Smrg int isstdin = 0; 118cbc4e2beSmrg const char *chars = "-#"; 119eaef79e5Smrg int i; 120eaef79e5Smrg unsigned int width, height; 121eaef79e5Smrg unsigned char *data; 122eaef79e5Smrg int x_hot, y_hot; 123eaef79e5Smrg int status; 124eaef79e5Smrg 125eaef79e5Smrg ProgramName = argv[0]; 126eaef79e5Smrg 127eaef79e5Smrg for (i = 1; i < argc; i++) { 128cbc4e2beSmrg const char *arg = argv[i]; 129eaef79e5Smrg 130eaef79e5Smrg if (arg[0] == '-') { 131eaef79e5Smrg switch (arg[1]) { 132eaef79e5Smrg case '\0': 133eaef79e5Smrg filename = NULL; 134eaef79e5Smrg continue; 135eaef79e5Smrg case 'c': 136d1a7ce7bSmrg if (++i >= argc) { 137d1a7ce7bSmrg fprintf(stderr, "%s: -chars requires an argument\n", 138d1a7ce7bSmrg ProgramName); 139433d0511Smrg usage(1); 140d1a7ce7bSmrg } 141eaef79e5Smrg chars = argv[i]; 142eaef79e5Smrg continue; 143433d0511Smrg case 'h': 144433d0511Smrg if (strcmp(arg, "-help") == 0) { 145433d0511Smrg usage(0); 146433d0511Smrg } 147433d0511Smrg goto unknown; 148433d0511Smrg case 'v': 149433d0511Smrg if (strcmp(arg, "-version") == 0) { 150433d0511Smrg puts(PACKAGE_STRING); 151433d0511Smrg exit(0); 152433d0511Smrg } 153433d0511Smrg goto unknown; 154eaef79e5Smrg default: 155433d0511Smrg unknown: 156d1a7ce7bSmrg fprintf(stderr, "%s: unrecognized option '%s'\n", 157d1a7ce7bSmrg ProgramName, argv[i]); 158433d0511Smrg usage(1); 159eaef79e5Smrg } 160eaef79e5Smrg } else { 161eaef79e5Smrg filename = arg; 162eaef79e5Smrg } 163eaef79e5Smrg } 164eaef79e5Smrg 165eaef79e5Smrg if (strlen (chars) != 2) { 166eaef79e5Smrg fprintf (stderr, 167eaef79e5Smrg "%s: bad character list \"%s\", must have exactly 2 characters\n", 168eaef79e5Smrg ProgramName, chars); 169eaef79e5Smrg exit (1); 170eaef79e5Smrg } 171eaef79e5Smrg 172eaef79e5Smrg if (!filename) { 173eaef79e5Smrg filename = copy_stdin (); 174eaef79e5Smrg isstdin = 1; 175eaef79e5Smrg } 176eaef79e5Smrg 177eaef79e5Smrg status = XmuReadBitmapDataFromFile (filename, &width, &height, &data, 178eaef79e5Smrg &x_hot, &y_hot); 179eaef79e5Smrg if (isstdin) (void) unlink (filename); /* don't need it anymore */ 180eaef79e5Smrg if (status != BitmapSuccess) { 181eaef79e5Smrg fprintf (stderr, "%s: unable to read bitmap from file \"%s\"\n", 182eaef79e5Smrg ProgramName, isstdin ? "(stdin)" : filename); 183eaef79e5Smrg exit (1); 184eaef79e5Smrg } 185eaef79e5Smrg 186eaef79e5Smrg print_scanline (width, height, data, chars); 187eaef79e5Smrg exit (0); 188eaef79e5Smrg} 189eaef79e5Smrg 190eaef79e5Smrgstatic void 191cbc4e2beSmrgprint_scanline (unsigned int width, 192cbc4e2beSmrg unsigned int height, 193cbc4e2beSmrg unsigned const char *data, 194cbc4e2beSmrg const char *chars) 195eaef79e5Smrg{ 196cbc4e2beSmrg unsigned const char *dp = data; 197eaef79e5Smrg int row, column; 198cbc4e2beSmrg static unsigned const char masktable[] = { 199eaef79e5Smrg 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; 200eaef79e5Smrg int padded = ((width & 7) != 0); 201eaef79e5Smrg 202eaef79e5Smrg for (row = 0; row < height; row++) { 203eaef79e5Smrg for (column = 0; column < width; column++) { 204eaef79e5Smrg int i = (column & 7); 205eaef79e5Smrg 206eaef79e5Smrg if (*dp & masktable[i]) { 207eaef79e5Smrg putchar (chars[1]); 208eaef79e5Smrg } else { 209eaef79e5Smrg putchar (chars[0]); 210eaef79e5Smrg } 211eaef79e5Smrg 212eaef79e5Smrg if (i == 7) dp++; 213eaef79e5Smrg } 214eaef79e5Smrg putchar ('\n'); 215eaef79e5Smrg if (padded) dp++; 216eaef79e5Smrg } 217eaef79e5Smrg return; 218eaef79e5Smrg} 219eaef79e5Smrg 220