Path: utzoo!attcan!uunet!wyse!mikew From: mikew@wyse.wyse.com (Mike Wexler) Newsgroups: comp.sources.x Subject: v02i076: XReadBitmapFile() that reads Suntools icons, Sun rasterfile, Part01/02 Message-ID: <1964@wyse.wyse.com> Date: 4 Jan 89 19:20:23 GMT Organization: Wyse Technology, San Jose Lines: 1825 Approved: mikew@wyse.com Submitted-by: mic@emx.utexas.edu (Mic Kaczmarczik) Posting-number: Volume 2, Issue 76 Archive-name: newrbf/part01 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'README' <<'END_OF_FILE' XThis directory contains versions of the X 11, Release 3 image file Xreading routines that can read Suntools icons and single-plane Sun Xrasterfiles (both unencoded and run-length byte encoded formats), as Xwell as X 11 bitmap format files. Also included are programs to Xdisplay bitmaps in an X window using the routines, and to convert X Xbitmap format files into Sun rasterfiles. X XThis code is likely most useful to Sun users, but it does work on Xother systems. I have tested this code on Suns, VAXen (under Ultrix Xand 4.3 BSD), a Mac II running A/UX, an Encore Multimax, and a Convex, Xso it seems to be relatively portable. X XX 11 clients that link in the routines won't notice any difference Xbetween files of various formats; they just get a pixmap as the result Xof the function call, as normal. The known image formats are tried Xsequentially until either a pixmap is returned or all the formats have Xbeen tried. The order in which formats are tried is: X X 11 bitmaps X Suntools icons X Sun rasterfiles X XThe ``native'' and most commonly used format (X 11 bitmaps) comes Xfirst. Suntools icons are next because (at least around here) they Xare used quite frequently as icons and widget pixmap images, whereas Xrasterfile format images are usually much larger and mainly used as Xroot window backgrounds. X XI have also included xshow, a program that displays bitmap image files Xon an X 11 display, so you can test the routines. (I used to use Xxsetroot to look at images before I had this :-). A last-minute Xaddition is a slightly cleaned up version of the program I used to Xconvert the Poskanzer bitmap collection into Sun rasterfile format to Xsave space. This program, like the library routines, has the Xadvantage of working on machines other than Suns. X XInstallation X------------ X XThe files XRdBitF.c and RdBitF.c are replacements for X$(TOP)/lib/X/XRdBitF.c and $(TOP)/lib/Xmu/RdBitF.c respectively, where X$(TOP) represents the top level of your X 11 Release 3 build tree. XSimply rename the distribution versions to something else (for example XXRdBitF.c.orig), copy the new files into their respective places, Xrebuild the X and Xmu libraries, and relink any clients that you want Xto use the new routines in. X XOnce the library is rebuilt, clients such xterm, xsetroot, window Xmanagers such as twm, and anything using the Release 3 X Toolkit X(which allows you to define pixmap resources for widgets) are good Xcandidates for relinking with the updated library. X XIf you want (or have) to keep your X 11 library in its original state, Xyou can compile XRdBitF.c and RdBitF.c by themselves, but you will Xstill need the private include files used to build the X and Xmu Xlibraries, found in $(TOP)/lib/X and $(TOP)/lib/Xmu. Once the routines Xare compiled, simply link them in ahead of the X 11 library on the X`cc' command line, and they'll be used in preference to the versions Xin the X library: X cc -o myprog myprog.c XRdBitF.o -lX11 X XAn Imakefile is included. I've also included a more conventional XMakefile (Makefile.noimake) that does the same thing; you will likely Xhave to edit the first few lines to make the program compile at your Xsite. Once that's done, type X make -f Makefile.noimake X Xto compile and link xshow and x11toras. Sorry, but I don't have a man Xpage for x11toras. X XCredits X------- X XThe library routines are based on the X 11, Release 3 X and Xmu Xlibrary sources. The rasterfile uncompression code is from Martin XBoyer, posted to the Sun-Spots mailing list in summer 1988. Xshow is Xbased on Xmac by Patrick Naughton, from the contributed software Xdirectory on the X 11 Release 2 tape. Thanks to Patrick and Martin, Xand to everyone else who has contributed their software to the net -- Xthe wealth of useful programs and good examples has been of great Xvalue to me over the past few years. X XMic Kaczmarczik XUser Services Unix Support Group XUT Austin Computation Center XAustin, Texas X XInternet: mic@emx.utexas.edu XUUCP: ...!uunet!cs.utexas.edu!ut-emx!mic XBITNET: mic@utaivc XTHENET: utaivc::mic END_OF_FILE if test 4009 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(6845 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' X# Makefile generated by imake - do not edit! X# $XConsortium: imake.c,v 1.37 88/10/08 20:08:30 jim Exp $ X# X# The cpp used on this machine replaces all newlines and multiple tabs and X# spaces in a macro expansion with a single space. Imake tries to compensate X# for this, but is not always successful. X# X X########################################################################### X# X Window System Makefile generated from template file Imake.tmpl X# $XConsortium: Imake.tmpl,v 1.91 88/10/23 22:37:10 jim Exp $ X# X# Do not change the body of the imake template file. Server-specific X# parameters may be set in the appropriate .macros file; site-specific X# parameters (but shared by all servers) may be set in site.def. If you X# make any changes, you'll need to rebuild the makefiles using X# "make World" (at best) or "make Makefile; make Makefiles" (at least) in X# the top level directory. X# X# If your C preprocessor doesn't define any unique symbols, you'll need X# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing X# "make Makefile", "make Makefiles", or "make World"). X# X# If you absolutely can't get imake to work, you'll need to set the X# variables at the top of each Makefile as well as the dependencies at the X# bottom (makedepend will do this automatically). X# X X########################################################################### X# platform-specific configuration parameters - edit Sun.macros to change X X# platform: $XConsortium: Sun.macros,v 1.52 88/10/23 11:00:55 jim Exp $ X# operating system: SunOS 3.4 X XBOOTSTRAPCFLAGS = X AS = as X CC = cc X CPP = /lib/cpp X LD = ld X LINT = lint X INSTALL = install X TAGS = ctags X RM = rm -f X MV = mv X LN = ln -s X RANLIB = ranlib XRANLIBINSTFLAGS = -t X AR = ar clq X LS = ls X LINTOPTS = -axz X LINTLIBFLAG = -C X MAKE = make XSTD_CPP_DEFINES = X STD_DEFINES = X X########################################################################### X# site-specific configuration parameters - edit site.def to change X X# site: $XConsortium: site.def,v 1.16 88/10/12 10:30:24 jim Exp $ X X########################################################################### X# definitions common to all Makefiles - do not edit X X SHELL = /bin/sh X X DESTDIR = /global X USRLIBDIR = $(DESTDIR)/lib X BINDIR = $(DESTDIR)/bin/X11 X INCDIR = $(DESTDIR)/include X ADMDIR = $(DESTDIR)/usr/adm X LIBDIR = $(USRLIBDIR)/X11 X LINTLIBDIR = $(USRLIBDIR)/lint X FONTDIR = $(LIBDIR)/fonts X XINITDIR = $(LIBDIR)/xinit X XDMDIR = $(LIBDIR)/xdm X UWMDIR = $(LIBDIR)/uwm X AWMDIR = $(LIBDIR)/awm X TWMDIR = $(LIBDIR)/twm X DTDIR = $(LIBDIR)/dt X MANPATH = /usr/man X MANSOURCEPATH = $(MANPATH)/man X MANDIR = $(MANSOURCEPATH)n X LIBMANDIR = $(MANSOURCEPATH)n3 X XAPPLOADDIR = $(LIBDIR)/app-defaults X X INSTBINFLAGS = -m 0755 X INSTUIDFLAGS = -m 4755 X INSTLIBFLAGS = -m 0664 X INSTINCFLAGS = -m 0444 X INSTMANFLAGS = -m 0444 X INSTAPPFLAGS = -m 0444 X INSTKMEMFLAGS = -m 4755 X FCFLAGS = -t X CDEBUGFLAGS = -O X X PATHSEP = / X DEPEND = $(BINDIR)/makedepend X IMAKE = $(BINDIR)/imake X RGB = $(LIBDIR)/rgb X FC = $(BINDIR)/bdftosnf X MKFONTDIR = $(BINDIR)/mkfontdir X MKDIRHIER = $(BINDIR)/mkdirhier.sh X X CFLAGS = $(CDEBUGFLAGS) $(INCLUDES) $(STD_DEFINES) $(DEFINES) X LINTFLAGS = $(LINTOPTS) $(INCLUDES) $(STD_DEFINES) $(DEFINES) -DLINT X LDFLAGS = $(CDEBUGFLAGS) -L$(USRLIBDIR) $(SYS_LIBRARIES) $(SYSAUX_LIBRARIES) X X IRULESRC = $(LIBDIR)/imake.includes X X EXTENSIONLIB = $(USRLIBDIR)/libext.a X XLIB = $(USRLIBDIR)/libX11.a X XMULIB = $(USRLIBDIR)/libXmu.a X OLDXLIB = $(USRLIBDIR)/liboldX.a X XTOOLLIB = $(USRLIBDIR)/libXt.a X XAWLIB = $(USRLIBDIR)/libXaw.a X LINTXLIB = $(USRLIBDIR)/llib-lX11.ln X LINTXMU = $(USRLIBDIR)/llib-lXmu.ln X LINTXTOOL = $(USRLIBDIR)/llib-lXt.ln X LINTXAW = $(USRLIBDIR)/llib-lXaw.ln X INCLUDES = -I$(INCDIR) X MACROFILE = Sun.macros X ICONFIGFILES = $(IRULESRC)/Imake.tmpl \ X $(IRULESRC)/$(MACROFILE) $(IRULESRC)/site.def X IMAKE_DEFINES = X IMAKE_CMD = $(NEWTOP)$(IMAKE) -TImake.tmpl -I$(NEWTOP)$(IRULESRC) \ X -s Makefile $(IMAKE_DEFINES) X RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a \ X .emacs_* tags TAGS make.log MakeOut X X########################################################################### X# rules: $XConsortium: Imake.rules,v 1.71 88/10/23 22:46:34 jim Exp $ X X########################################################################### X# start of Imakefile X X# X# Imakefile for xshow and x11toras, using enhanced XReadBitmapFile() X# X X SRCS1 = xshow.c xshow.icon xshow.cursor X OBJS1 = xshow.o XRdBitF.o X SRCS2 = x11toras.c X OBJS2 = x11toras.o X PROGRAMS = xshow x11toras XLOCAL_LIBRARIES = $(XLIB) X DEFINES = -I/src/x/x11.3/lib/X X X OBJS = $(OBJS1) $(OBJS2) $(OBJS3) X SRCS = $(SRCS1) $(SRCS2) $(SRCS3) X Xall:: $(PROGRAMS) X Xxshow: $(OBJS1) $(XLIB) X $(RM) $@ X $(CC) -o $@ $(OBJS1) $(XLIB) $(LDFLAGS) $(SYSLAST_LIBRARIES) X Xinstall:: xshow X $(INSTALL) -c $(INSTALLFLAGS) xshow $(BINDIR) X Xinstall.man:: xshow.man X $(INSTALL) -c $(INSTMANFLAGS) xshow.man $(MANDIR)/xshow.n X Xrelink:: X $(RM) $(PROGRAMS) X $(MAKE) $(MFLAGS) $(PROGRAMS) X Xdepend:: $(DEPEND) X Xdepend:: X $(DEPEND) -s "# DO NOT DELETE" -- $(CFLAGS) -- $(SRCS) X X$(DEPEND): X @echo "making $@"; \ X cd $(DEPENDSRC); $(MAKE) X Xclean:: X $(RM) $(PROGRAMS) X Xx11toras: $(OBJS2) X $(RM) $@ X $(CC) -o $@ $(OBJS2) $(LDFLAGS) $(SYSLAST_LIBRARIES) X Xrelink:: X $(RM) x11toras X $(MAKE) $(MFLAGS) x11toras X Xclean:: X $(RM) x11toras X X########################################################################### X# Imake.tmpl common rules for all Makefiles - do not edit X Xemptyrule:: X Xclean:: X $(RM_CMD) \#* X XMakefile:: $(IMAKE) X XMakefile:: Imakefile \ X $(IRULESRC)/Imake.tmpl \ X $(IRULESRC)/Imake.rules \ X $(IRULESRC)/site.def \ X $(IRULESRC)/$(MACROFILE) X -@if [ -f Makefile ]; then \ X echo "$(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \ X $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \ X else exit 0; fi X $(IMAKE_CMD) -DTOPDIR=$(TOP) X X$(IMAKE): X @echo "making $@"; \ X cd $(IMAKESRC); $(MAKE) BOOTSTRAPCFLAGS=$(BOOTSTRAPCFLAGS) X Xtags:: X $(TAGS) -w *.[ch] X $(TAGS) -xw *.[ch] > TAGS X X########################################################################### X# empty rules for directories that do not have SUBDIRS - do not edit X Xinstall:: X @echo "install done" X Xinstall.man:: X @echo "install.man done" X XMakefiles:: X X########################################################################### X# dependencies generated by makedepend X END_OF_FILE if test 6845 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'RdBitF.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'RdBitF.c'\" else echo shar: Extracting \"'RdBitF.c'\" \(18757 characters\) sed "s/^X//" >'RdBitF.c' <<'END_OF_FILE' X/* X * $XConsortium: RdBitF.c,v 1.4 88/09/13 12:06:36 jim Exp $ X * X * Copyright 1988 Massachusetts Institute of Technology X * X * This file contains miscellaneous utility routines and is not part of the X * Xlib standard. X * X * Public entry points: X * X * XmuReadBitmapDataFromFile read X10 or X11 format bitmap files X * and return data X * X * Note that this file and ../X/XRdBitF.c look very similar.... Keep them X * that way (but don't use common source code so that people can have one X * without the other). X */ X X#include "copyright.h" X X/* X * Based on an optimized version provided by Jim Becker, Auguest 5, 1988. X */ X X#include X#include X#include X#include X#include X X X#define MAX_SIZE 255 X#define Xmalloc(size) malloc(size) X#define Xfree(ptr) free(ptr) Xchar *malloc(); X X/* X * The data returned by the following routine is always in left-most byte X * first and left-most bit first. If it doesn't return BitmapSuccess then X * its arguments won't have been touched. This routine should look as much X * like the Xlib routine XReadBitmapfile as possible. X */ Xint XmuReadBitmapDataFromFile (filename, width, height, datap, x_hot, y_hot) X char *filename; X unsigned int *width, *height; /* RETURNED */ X unsigned char **datap; /* RETURNED */ X int *x_hot, *y_hot; /* RETURNED */ X{ X int status; X FILE *fstream = NULL, *fopen(); X X#define RETURN(code) { if (fstream) fclose(fstream); return (code); } X X if ((fstream = fopen(filename, "r")) == NULL) X RETURN (BitmapOpenFailed); X X /* X11/10 bitmaps */ X status = _ReadBitmapDataFromFile(fstream, width, height, datap, x_hot, y_hot); X if (status != BitmapFileInvalid) X RETURN (status); X X /* Suntools icons */ X fseek(fstream, 0L, 0); X status = _ReadIconDataFromFile(fstream, width, height, datap, x_hot, y_hot); X if (status != BitmapFileInvalid) X RETURN (status); X X /* Sun rasterfiles */ X fseek(fstream, 0L, 0); X status = _ReadRasterDataFromFile(fstream, width, height, datap, x_hot, y_hot); X X fclose(fstream); X return (status); X} X X/* shared data for the image read/parse logic */ Xstatic short hexTable[256]; /* conversion value */ Xstatic Bool initialized = False; /* easier to fill in at run time */ X X X/* X * Table index for the hex values. Initialized once, first time. X * Used for translation value or delimiter significance lookup. X */ Xstatic void initHexTable() X{ X /* X * We build the table at run time for several reasons: X * X * 1. portable to non-ASCII machines. X * 2. still reentrant since we set the init flag after setting table. X * 3. easier to extend. X * 4. less prone to bugs. X */ X hexTable['0'] = 0; hexTable['1'] = 1; X hexTable['2'] = 2; hexTable['3'] = 3; X hexTable['4'] = 4; hexTable['5'] = 5; X hexTable['6'] = 6; hexTable['7'] = 7; X hexTable['8'] = 8; hexTable['9'] = 9; X hexTable['A'] = 10; hexTable['B'] = 11; X hexTable['C'] = 12; hexTable['D'] = 13; X hexTable['E'] = 14; hexTable['F'] = 15; X hexTable['a'] = 10; hexTable['b'] = 11; X hexTable['c'] = 12; hexTable['d'] = 13; X hexTable['e'] = 14; hexTable['f'] = 15; X X /* delimiters of significance are flagged w/ negative value */ X hexTable[' '] = -1; hexTable[','] = -1; X hexTable['}'] = -1; hexTable['\n'] = -1; X hexTable['\t'] = -1; X X initialized = True; X} X X/* X * read next hex value in the input stream, return -1 if EOF X */ Xstatic NextInt (fstream) X FILE *fstream; X{ X int ch; X int value = 0; X int gotone = 0; X int done = 0; X X /* loop, accumulate hex value until find delimiter */ X /* skip any initial delimiters found in read stream */ X X while (!done) { X ch = getc(fstream); X if (ch == EOF) { X value = -1; X done++; X } else { X /* trim high bits, check type and accumulate */ X ch &= 0xff; X if (isascii(ch) && isxdigit(ch)) { X value = (value << 4) + hexTable[ch]; X gotone++; X } else if ((hexTable[ch]) < 0 && gotone) X done++; X } X } X return value; X} X X X/* X * Read X bitmap files (this code, with the exception of replacing the X * file name argument with a FILE *, is the R3 XmuReadBitmapDataFromFile()). X */ X Xstatic int _ReadBitmapDataFromFile (fstream, width, height, datap, x_hot, y_hot) X FILE *fstream; X unsigned int *width, *height; /* RETURNED */ X unsigned char **datap; /* RETURNED */ X int *x_hot, *y_hot; /* RETURNED */ X{ X unsigned char *data = NULL; /* working variable */ X char line[MAX_SIZE]; /* input line from file */ X int size; /* number of bytes of data */ X char name_and_type[MAX_SIZE]; /* an input line */ X char *type; /* for parsing */ X int value; /* from an input line */ X int version10p; /* boolean, old format */ X int padding; /* to handle alignment */ X int bytes_per_line; /* per scanline of data */ X unsigned int ww = 0; /* width */ X unsigned int hh = 0; /* height */ X int hx = -1; /* x hotspot */ X int hy = -1; /* y hotspot */ X X /* first time initialization */ X if (initialized == False) initHexTable(); X X /* error cleanup and return macro */ X#ifdef RETURN X#undef RETURN X#endif X#define RETURN(code) { if (data) free (data); return code; } X X while (fgets(line, MAX_SIZE, fstream)) { X if (strlen(line) == MAX_SIZE-1) { X RETURN (BitmapFileInvalid); X } X if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) { X if (!(type = rindex(name_and_type, '_'))) X type = name_and_type; X else X type++; X X if (!strcmp("width", type)) X ww = (unsigned int) value; X if (!strcmp("height", type)) X hh = (unsigned int) value; X if (!strcmp("hot", type)) { X if (type-- == name_and_type || type-- == name_and_type) X continue; X if (!strcmp("x_hot", type)) X hx = value; X if (!strcmp("y_hot", type)) X hy = value; X } X continue; X } X X if (sscanf(line, "static short %s = {", name_and_type) == 1) X version10p = 1; X else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1) X version10p = 0; X else if (sscanf(line, "static char %s = {", name_and_type) == 1) X version10p = 0; X else X continue; X X if (!(type = rindex(name_and_type, '_'))) X type = name_and_type; X else X type++; X X if (strcmp("bits[]", type)) X continue; X X if (!ww || !hh) X RETURN (BitmapFileInvalid); X X if ((ww % 16) && ((ww % 16) < 9) && version10p) X padding = 1; X else X padding = 0; X X bytes_per_line = (ww+7)/8 + padding; X X size = bytes_per_line * hh; X data = (unsigned char *) Xmalloc ((unsigned int) size); X if (!data) X RETURN (BitmapNoMemory); X X if (version10p) { X unsigned char *ptr; X int bytes; X X for (bytes=0, ptr=data; bytes> 8; X } X } else { X unsigned char *ptr; X int bytes; X X for (bytes=0, ptr=data; bytes 0x80 0x03 0xYZ X * X * exception: 0x80 (alone) => 0x80 0x00 (note missing byte) X * and NOT 0x80 0x00 0x80 X * but 0x80 0x80 => 0x80 0x01 0x80 (follows general rule) X * X * Even better, here is a function that does the decoding: X * (I don't have any for encoding) X * X * It worked for at least a year on all sorts of images without a burp. X * Good luck! X * X * Martin Boyer amadeus!gamin@mcgill-vision.uucp X * Institut de recherche d'Hydro-Quebec sun!sunlegende!amadeus!gamin X * Varennes, QC, Canada J0L 2P0 +1 514 652-8136 X */ X X/* X * First argument is a pointer to the encoded array of pixels. X * Second is a pointer to enough space for the decoded array of pixels, X * which will be ras_width (rounded up to a short) * ras_height X * * ras_depth long X * Third is length of input (in bytes) (ras_length). X * X * Returns length of decoded output, can be used to verify correct X * encoding/decoding. X */ X Xunsigned int Xdecode_image(inpix, outpix, lin) X register unsigned char *inpix, *outpix; X register unsigned int lin; X{ X register unsigned char value; X register unsigned int n; X unsigned char *outpix_0; X X outpix_0 = outpix; X while (lin) { X if ((value = *inpix++) == 0x80) { X if ((n = *inpix++) == 0) { X *outpix++ = 0x80; /* special: 0x80 0x00 ==> 0x80 */ X lin -= 2; X } else { X for (value = *inpix++, n++; n; n--) X *outpix++ = value; X lin -= 3; X } X } else { X *outpix++ = value; X lin--; X } X } X return (outpix - outpix_0); X} X X/* X * Treat cp[0] through cp[3] as a big-endian 32-bit longword and convert X * it into an integer. X */ X Xstatic msb_int(cp) Xregister unsigned char *cp; X{ X return ((cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3]); X} X X/* X * 256-byte table for quickly reversing the bits in an unsigned 8-bit char, X * used to convert between MSBFirst and LSBFirst image formats. X */ X Xstatic char revtable[256] = { X 0, -128, 64, -64, 32, -96, 96, -32, X 16, -112, 80, -48, 48, -80, 112, -16, X 8, -120, 72, -56, 40, -88, 104, -24, X 24, -104, 88, -40, 56, -72, 120, -8, X 4, -124, 68, -60, 36, -92, 100, -28, X 20, -108, 84, -44, 52, -76, 116, -12, X 12, -116, 76, -52, 44, -84, 108, -20, X 28, -100, 92, -36, 60, -68, 124, -4, X 2, -126, 66, -62, 34, -94, 98, -30, X 18, -110, 82, -46, 50, -78, 114, -14, X 10, -118, 74, -54, 42, -86, 106, -22, X 26, -102, 90, -38, 58, -70, 122, -6, X 6, -122, 70, -58, 38, -90, 102, -26, X 22, -106, 86, -42, 54, -74, 118, -10, X 14, -114, 78, -50, 46, -82, 110, -18, X 30, -98, 94, -34, 62, -66, 126, -2, X 1, -127, 65, -63, 33, -95, 97, -31, X 17, -111, 81, -47, 49, -79, 113, -15, X 9, -119, 73, -55, 41, -87, 105, -23, X 25, -103, 89, -39, 57, -71, 121, -7, X 5, -123, 69, -59, 37, -91, 101, -27, X 21, -107, 85, -43, 53, -75, 117, -11, X 13, -115, 77, -51, 45, -83, 109, -19, X 29, -99, 93, -35, 61, -67, 125, -3, X 3, -125, 67, -61, 35, -93, 99, -29, X 19, -109, 83, -45, 51, -77, 115, -13, X 11, -117, 75, -53, 43, -85, 107, -21, X 27, -101, 91, -37, 59, -69, 123, -5, X 7, -121, 71, -57, 39, -89, 103, -25, X 23, -105, 87, -41, 55, -73, 119, -9, X 15, -113, 79, -49, 47, -81, 111, -17, X 31, -97, 95, -33, 63, -65, 127, -1, X}; X X/* X * Convert pixrect-format data into X 11 format data, which means reversing X * the bits, and removing the extra byte of padding. Removing the padding X * is done by backing up at the end of a pixrect line, if necessary. X */ X Xstatic pixtoX11(data, width, height) Xunsigned char *data; Xint width, height; X{ X register unsigned char tmp, *cp, *end, *datap; X int row, linewidth, unpad = False; X X linewidth = ((width + 7) / 8); X if (linewidth & 1) { X linewidth++; X unpad = True; X } X X datap = data; X for (row = 0 ; row < height ; row++) { X cp = data + (row * linewidth); X end = cp + linewidth; X while (cp < end) X *(datap++) = revtable[*(cp++)]; X if (unpad) X datap--; /* back up to unpad line */ X } X} END_OF_FILE if test 18757 -ne `wc -c <'RdBitF.c'`; then echo shar: \"'RdBitF.c'\" unpacked with wrong size! fi # end of 'RdBitF.c' fi if test -f 'XRdBitF.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'XRdBitF.c'\" else echo shar: Extracting \"'XRdBitF.c'\" \(20928 characters\) sed "s/^X//" >'XRdBitF.c' <<'END_OF_FILE' X/* Copyright, 1987, Massachusetts Institute of Technology */ X X#include "X11/copyright.h" X X/* X * Code to read bitmaps from disk files. Interprets X * data from X10 and X11 bitmap files and creates X * Pixmap representations of files. Returns Pixmap X * ID and specifics about image. X * X * Modified for speedup by Jim Becker, changed image X * data parsing logic (removed some fscanf()s). X * Aug 5, 1988 X * X * Sun rasterfile and Suntools icon support by X * Mic Kaczmarczik, November 1988. The rasterfile and X * icon support can be used on machines other than Suns. X * In particular, it works fine on VAXen and Encores. X * X * Uses code to decode run-length encoded Sun rasterfiles X * by Martin Boyer. X * X * Note that this file and ../Xmu/RdBitF.c look very similar.... Keep them X * that way (but don't use common source code so that people can have one X * without the other). X */ X X#include X#include "Xlib.h" X#include "Xutil.h" X#include "Xlibint.h" X#include X#include X X X#define MAX_SIZE 255 X X/* X * XReadBitmapFile is now a front end for different routines to read X * in bitmap files. The order in which formats are tried is somewhat X * arbitrary, but I figure X bitmaps should come first, then Suntools X * icons (which will probably be used more often than big rasterfiles), X * and finally rasterfiles. X */ X Xint XReadBitmapFile(display, d, filename, width, height, bitmap, x_hot, y_hot) X Display *display; X Drawable d; X char *filename; X unsigned int *width, *height; /* RETURNED */ X Pixmap *bitmap; /* RETURNED */ X int *x_hot, *y_hot; /* RETURNED */ X{ X int status; X FILE *fstream = NULL, *fopen(); X X#define RETURN(code) { if (fstream) fclose(fstream); return (code); } X X if ((fstream = fopen(filename, "r")) == NULL) X RETURN (BitmapOpenFailed); X X /* X11/10 bitmaps */ X status = _ReadBitmapFile(display, d, fstream, X width, height, bitmap, x_hot, y_hot); X if (status != BitmapFileInvalid) X RETURN (status); X X /* Suntools icons */ X fseek(fstream, 0L, 0); X status = _ReadIconFile(display, d, fstream, width, height, X bitmap, x_hot, y_hot); X if (status != BitmapFileInvalid) X RETURN (status); X X /* Sun rasterfiles */ X fseek(fstream, 0L, 0); X status = _ReadRasterFile(display, d, fstream, X width, height, bitmap, x_hot, y_hot); X X fclose(fstream); X return (status); X} X X/* shared data for the image read/parse logic */ Xstatic short hexTable[256]; /* conversion value */ Xstatic Bool initialized = False; /* easier to fill in at run time */ X X X/* X * Table index for the hex values. Initialized once, first time. X * Used for translation value or delimiter significance lookup. X */ Xstatic void initHexTable() X{ X /* X * We build the table at run time for several reasons: X * X * 1. portable to non-ASCII machines. X * 2. still reentrant since we set the init flag after setting table. X * 3. easier to extend. X * 4. less prone to bugs. X */ X hexTable['0'] = 0; hexTable['1'] = 1; X hexTable['2'] = 2; hexTable['3'] = 3; X hexTable['4'] = 4; hexTable['5'] = 5; X hexTable['6'] = 6; hexTable['7'] = 7; X hexTable['8'] = 8; hexTable['9'] = 9; X hexTable['A'] = 10; hexTable['B'] = 11; X hexTable['C'] = 12; hexTable['D'] = 13; X hexTable['E'] = 14; hexTable['F'] = 15; X hexTable['a'] = 10; hexTable['b'] = 11; X hexTable['c'] = 12; hexTable['d'] = 13; X hexTable['e'] = 14; hexTable['f'] = 15; X X /* delimiters of significance are flagged w/ negative value */ X hexTable[' '] = -1; hexTable[','] = -1; X hexTable['}'] = -1; hexTable['\n'] = -1; X hexTable['\t'] = -1; X X initialized = True; X} X X/* X * read next hex value in the input stream, return -1 if EOF X */ Xstatic NextInt (fstream) X FILE *fstream; X{ X int ch; X int value = 0; X int gotone = 0; X int done = 0; X X /* loop, accumulate hex value until find delimiter */ X /* skip any initial delimiters found in read stream */ X X while (!done) { X ch = getc(fstream); X if (ch == EOF) { X value = -1; X done++; X } else { X /* trim high bits, check type and accumulate */ X ch &= 0xff; X if (isascii(ch) && isxdigit(ch)) { X value = (value << 4) + hexTable[ch]; X gotone++; X } else if ((hexTable[ch]) < 0 && gotone) X done++; X } X } X return value; X} X X X/* X * Read X bitmap files (this code, with the exception of replacing the X * file name argument with a FILE *, is the R3 XReadBitmapFile()). X */ X X_ReadBitmapFile (display, d, fstream, width, height, pixmap, x_hot, y_hot) X Display *display; X Drawable d; X FILE *fstream; X unsigned int *width, *height; /* RETURNED */ X Pixmap *pixmap; /* RETURNED */ X int *x_hot, *y_hot; /* RETURNED */ X{ X Pixmap pix; /* value to return */ X unsigned char *data = NULL; /* working variable */ X char line[MAX_SIZE]; /* input line from file */ X int size; /* number of bytes of data */ X char name_and_type[MAX_SIZE]; /* an input line */ X char *type; /* for parsing */ X int value; /* from an input line */ X int version10p; /* boolean, old format */ X int padding; /* to handle alignment */ X int bytes_per_line; /* per scanline of data */ X unsigned int ww = 0; /* width */ X unsigned int hh = 0; /* height */ X int hx = -1; /* x hotspot */ X int hy = -1; /* y hotspot */ X X /* first time initialization */ X if (initialized == False) initHexTable(); X X /* error cleanup and return macro */ X#ifdef RETURN X#undef RETURN X#endif X#define RETURN(code) { if (data) free (data); return code; } X X while (fgets(line, MAX_SIZE, fstream)) { X if (strlen(line) == MAX_SIZE-1) { X RETURN (BitmapFileInvalid); X } X if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) { X if (!(type = rindex(name_and_type, '_'))) X type = name_and_type; X else X type++; X X if (!strcmp("width", type)) X ww = (unsigned int) value; X if (!strcmp("height", type)) X hh = (unsigned int) value; X if (!strcmp("hot", type)) { X if (type-- == name_and_type || type-- == name_and_type) X continue; X if (!strcmp("x_hot", type)) X hx = value; X if (!strcmp("y_hot", type)) X hy = value; X } X continue; X } X X if (sscanf(line, "static short %s = {", name_and_type) == 1) X version10p = 1; X else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1) X version10p = 0; X else if (sscanf(line, "static char %s = {", name_and_type) == 1) X version10p = 0; X else X continue; X X if (!(type = rindex(name_and_type, '_'))) X type = name_and_type; X else X type++; X X if (strcmp("bits[]", type)) X continue; X X if (!ww || !hh) X RETURN (BitmapFileInvalid); X X if ((ww % 16) && ((ww % 16) < 9) && version10p) X padding = 1; X else X padding = 0; X X bytes_per_line = (ww+7)/8 + padding; X X size = bytes_per_line * hh; X data = (unsigned char *) Xmalloc ((unsigned int) size); X if (!data) X RETURN (BitmapNoMemory); X X if (version10p) { X unsigned char *ptr; X int bytes; X X for (bytes=0, ptr=data; bytes> 8; X } X } else { X unsigned char *ptr; X int bytes; X X for (bytes=0, ptr=data; bytes 0x80 0x03 0xYZ X * X * exception: 0x80 (alone) => 0x80 0x00 (note missing byte) X * and NOT 0x80 0x00 0x80 X * but 0x80 0x80 => 0x80 0x01 0x80 (follows general rule) X * X * Even better, here is a function that does the decoding: X * (I don't have any for encoding) X * X * It worked for at least a year on all sorts of images without a burp. X * Good luck! X * X * Martin Boyer amadeus!gamin@mcgill-vision.uucp X * Institut de recherche d'Hydro-Quebec sun!sunlegende!amadeus!gamin X * Varennes, QC, Canada J0L 2P0 +1 514 652-8136 X */ X X/* X * First argument is a pointer to the encoded array of pixels. X * Second is a pointer to enough space for the decoded array of pixels, X * which will be ras_width (rounded up to a short) * ras_height X * * ras_depth long X * Third is length of input (in bytes) (ras_length). X * X * Returns length of decoded output, can be used to verify correct X * encoding/decoding. X */ X Xunsigned int Xdecode_image(inpix, outpix, lin) X register unsigned char *inpix, *outpix; X register unsigned int lin; X{ X register unsigned char value; X register unsigned int n; X unsigned char *outpix_0; X X outpix_0 = outpix; X while (lin) { X if ((value = *inpix++) == 0x80) { X if ((n = *inpix++) == 0) { X *outpix++ = 0x80; /* special: 0x80 0x00 ==> 0x80 */ X lin -= 2; X } else { X for (value = *inpix++, n++; n; n--) X *outpix++ = value; X lin -= 3; X } X } else { X *outpix++ = value; X lin--; X } X } X return (outpix - outpix_0); X} X X/* X * Treat cp[0] through cp[3] as a big-endian 32-bit longword and convert X * it into an integer. X */ X Xstatic msb_int(cp) Xregister unsigned char *cp; X{ X return ((cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3]); X} X X/* X * 256-byte table for quickly reversing the bits in an unsigned 8-bit char, X * used to convert between MSBFirst and LSBFirst image formats. X */ X Xstatic char revtable[256] = { X 0, -128, 64, -64, 32, -96, 96, -32, X 16, -112, 80, -48, 48, -80, 112, -16, X 8, -120, 72, -56, 40, -88, 104, -24, X 24, -104, 88, -40, 56, -72, 120, -8, X 4, -124, 68, -60, 36, -92, 100, -28, X 20, -108, 84, -44, 52, -76, 116, -12, X 12, -116, 76, -52, 44, -84, 108, -20, X 28, -100, 92, -36, 60, -68, 124, -4, X 2, -126, 66, -62, 34, -94, 98, -30, X 18, -110, 82, -46, 50, -78, 114, -14, X 10, -118, 74, -54, 42, -86, 106, -22, X 26, -102, 90, -38, 58, -70, 122, -6, X 6, -122, 70, -58, 38, -90, 102, -26, X 22, -106, 86, -42, 54, -74, 118, -10, X 14, -114, 78, -50, 46, -82, 110, -18, X 30, -98, 94, -34, 62, -66, 126, -2, X 1, -127, 65, -63, 33, -95, 97, -31, X 17, -111, 81, -47, 49, -79, 113, -15, X 9, -119, 73, -55, 41, -87, 105, -23, X 25, -103, 89, -39, 57, -71, 121, -7, X 5, -123, 69, -59, 37, -91, 101, -27, X 21, -107, 85, -43, 53, -75, 117, -11, X 13, -115, 77, -51, 45, -83, 109, -19, X 29, -99, 93, -35, 61, -67, 125, -3, X 3, -125, 67, -61, 35, -93, 99, -29, X 19, -109, 83, -45, 51, -77, 115, -13, X 11, -117, 75, -53, 43, -85, 107, -21, X 27, -101, 91, -37, 59, -69, 123, -5, X 7, -121, 71, -57, 39, -89, 103, -25, X 23, -105, 87, -41, 55, -73, 119, -9, X 15, -113, 79, -49, 47, -81, 111, -17, X 31, -97, 95, -33, 63, -65, 127, -1, X}; X X/* X * Convert pixrect-format data into X 11 format data, which means reversing X * the bits, and removing the extra byte of padding. Removing the padding X * is done by backing up at the end of a pixrect line, if necessary. X */ X Xstatic pixtoX11(data, width, height) Xunsigned char *data; Xint width, height; X{ X register unsigned char tmp, *cp, *end, *datap; X int row, linewidth, unpad = False; X X linewidth = ((width + 7) / 8); X if (linewidth & 1) { X linewidth++; X unpad = True; X } X X datap = data; X for (row = 0 ; row < height ; row++) { X cp = data + (row * linewidth); X end = cp + linewidth; X while (cp < end) X *(datap++) = revtable[*(cp++)]; X if (unpad) X datap--; /* back up to unpad line */ X } X} X X X/* X * Emulate CreateBitmapFromData, but using parameters suitable for X * pixrect-format data. X */ Xstatic _CreateBitmapFromPixrectData(display, d, data, width, height) XDisplay *display; XDrawable d; Xchar *data; Xint width, height; X{ X GC gc; X XImage ximage; X Pixmap pix; X X pix = XCreatePixmap(display, d, width, height, 1); X if (pix == None) X return (pix); X X gc = XCreateGC(display, pix, (unsigned long)0, (XGCValues *)0); X X ximage.width = width; X ximage.height = height; X ximage.depth = 1; X ximage.xoffset = 0; X ximage.format = ZPixmap; X ximage.data = data; X ximage.byte_order = MSBFirst; X ximage.bitmap_unit = 8; X ximage.bitmap_bit_order = MSBFirst; X ximage.bitmap_pad = 16; X ximage.bytes_per_line = ((width + 15) / 16) * 2; X X XPutImage(display, pix, gc, &ximage, 0, 0, 0, 0, width, height); X XFreeGC(display, gc); X X return (pix); X} END_OF_FILE if test 20928 -ne `wc -c <'XRdBitF.c'`; then echo shar: \"'XRdBitF.c'\" unpacked with wrong size! fi # end of 'XRdBitF.c' fi if test -f 'xshow.cursor' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xshow.cursor'\" else echo shar: Extracting \"'xshow.cursor'\" \(564 characters\) sed "s/^X//" >'xshow.cursor' <<'END_OF_FILE' X#define bitmap_width 16 X#define bitmap_height 16 X#define bitmap_x_hot 2 X#define bitmap_y_hot 4 Xstatic char bitmap_bits[] = { X 0x00, 0x00, 0x80, 0x1f, 0x40, 0x08, 0x23, 0x04, 0x57, 0x05, 0x13, 0x04, X 0xd3, 0x05, 0x1f, 0x3c, 0x1c, 0x7c, 0x10, 0x64, 0x90, 0x74, 0x90, 0x64, X 0x90, 0x04, 0x88, 0x08, 0x84, 0x10, 0x7c, 0x1f}; Xstatic char bitmap_mask_bits[] = { X 0x80, 0x3f, 0xc0, 0x3f, 0xe7, 0x1f, 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, X 0xff, 0x3f, 0xff, 0x7f, 0xff, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xf8, 0xff, X 0xf8, 0x6f, 0xfc, 0x1f, 0xfe, 0x3f, 0xfe, 0x3f}; END_OF_FILE if test 564 -ne `wc -c <'xshow.cursor'`; then echo shar: \"'xshow.cursor'\" unpacked with wrong size! fi # end of 'xshow.cursor' fi echo shar: End of archive 1 \(of 2\). cp /dev/null ark1isdone MISSING="" for I in 1 2 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked both archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Mike Wexler(wyse!mikew) Phone: (408)433-1000 x1330 Moderator of comp.sources.x