1 /* $XConsortium: XbmUtils.c /main/4 1996/05/09 03:44:48 drk $ */
5 ** This module provides routines that allow a pixmap to be generated from
6 ** a _DtGrStream containing XBM data. The module is adapted from the
7 ** RdBitF.c module in the X11R6 version of libX11.
12 Copyright (c) 1987 X Consortium
14 Permission is hereby granted, free of charge, to any person obtaining
15 a copy of this software and associated documentation files (the
16 "Software"), to deal in the Software without restriction, including
17 without limitation the rights to use, copy, modify, merge, publish,
18 distribute, sublicense, and/or sell copies of the Software, and to
19 permit persons to whom the Software is furnished to do so, subject to
20 the following conditions:
22 The above copyright notice and this permission notice shall be included
23 in all copies or substantial portions of the Software.
25 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
26 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
28 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
29 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
30 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
31 OTHER DEALINGS IN THE SOFTWARE.
33 Except as contained in this notice, the name of the X Consortium shall
34 not be used in advertising or otherwise to promote the sale, use or
35 other dealings in this Software without prior written authorization
36 from the X Consortium.
41 * Code to read bitmaps from disk files. Interprets
42 * data from X10 and X11 bitmap files and creates
43 * Pixmap representations of files. Returns Pixmap
44 * ID and specifics about image.
46 * Modified for speedup by Jim Becker, changed image
47 * data parsing logic (removed some fscanf()s).
50 * Note that this file and ../Xmu/RdBitF.c look very similar.... Keep them
51 * that way (but don't use common source code so that people can have one
55 #include <X11/Xlibint.h>
57 #include <X11/Xutil.h>
61 #include "GraphicsP.h"
66 /* shared data for the image read/parse logic */
67 static short hexTable[256]; /* conversion value */
70 * Table index for the hex values. Initialized once, first time.
71 * Used for translation value or delimiter significance lookup.
73 static void initHexTable()
76 * We build the table at run time for several reasons:
78 * 1. portable to non-ASCII machines.
79 * 2. still reentrant since we set the init flag after setting table.
80 * 3. easier to extend.
81 * 4. less prone to bugs.
83 hexTable['0'] = 0; hexTable['1'] = 1;
84 hexTable['2'] = 2; hexTable['3'] = 3;
85 hexTable['4'] = 4; hexTable['5'] = 5;
86 hexTable['6'] = 6; hexTable['7'] = 7;
87 hexTable['8'] = 8; hexTable['9'] = 9;
88 hexTable['A'] = 10; hexTable['B'] = 11;
89 hexTable['C'] = 12; hexTable['D'] = 13;
90 hexTable['E'] = 14; hexTable['F'] = 15;
91 hexTable['a'] = 10; hexTable['b'] = 11;
92 hexTable['c'] = 12; hexTable['d'] = 13;
93 hexTable['e'] = 14; hexTable['f'] = 15;
95 /* delimiters of significance are flagged w/ negative value */
96 hexTable[' '] = -1; hexTable[','] = -1;
97 hexTable['}'] = -1; hexTable['\n'] = -1;
102 * read next hex value in the input stream, return -1 if EOF
104 static NextInt (fstream)
105 _DtGrStream *fstream;
112 /* loop, accumulate hex value until find delimiter */
113 /* skip any initial delimiters found in read stream */
115 _DtHelpProcessLock();
117 ch = _DtGrGetChar(fstream);
122 /* trim high bits, check type and accumulate */
124 if (isascii(ch) && isxdigit(ch)) {
125 value = (value << 4) + hexTable[ch];
127 } else if ((hexTable[ch]) < 0 && gotone)
131 _DtHelpProcessUnlock();
135 #if NeedFunctionPrototypes
136 int _DtGrReadBitmapStreamData (
137 _DtGrStream *fstream,
138 unsigned int *width, /* RETURNED */
139 unsigned int *height, /* RETURNED */
140 unsigned char **data, /* RETURNED */
141 int *x_hot, /* RETURNED */
142 int *y_hot) /* RETURNED */
144 int _DtGrReadBitmapStreamData (stream, width, height, data, x_hot, y_hot)
145 _DtGrStream *fstream;
146 unsigned int *width, *height; /* RETURNED */
147 unsigned char **data; /* RETURNED */
148 int *x_hot, *y_hot; /* RETURNED */
151 unsigned char *bits = NULL; /* working variable */
152 char line[MAX_SIZE]; /* input line from file */
153 int size; /* number of bytes of data */
154 char name_and_type[MAX_SIZE]; /* an input line */
155 char *type; /* for parsing */
156 int value; /* from an input line */
157 int version10p; /* boolean, old format */
158 int padding; /* to handle alignment */
159 int bytes_per_line; /* per scanline of data */
160 unsigned int ww = 0; /* width */
161 unsigned int hh = 0; /* height */
162 int hx = -1; /* x hotspot */
163 int hy = -1; /* y hotspot */
164 static Bool initialized = False; /* easier to fill in at run time */
166 /* first time initialization */
167 _DtHelpProcessLock();
168 if (initialized == False)
173 _DtHelpProcessUnlock();
175 /* error cleanup and return macro */
176 #define RETURN(code) \
177 { if (bits) Xfree ((char *)bits); return code; }
179 while (_DtGrGetString(line, MAX_SIZE, fstream)) {
180 if (strlen(line) == MAX_SIZE-1)
181 RETURN (BitmapFileInvalid);
182 if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) {
183 if (!(type = strrchr(name_and_type, '_')))
184 type = name_and_type;
188 if (!strcmp("width", type))
189 ww = (unsigned int) value;
190 if (!strcmp("height", type))
191 hh = (unsigned int) value;
192 if (!strcmp("hot", type)) {
193 if (type-- == name_and_type || type-- == name_and_type)
195 if (!strcmp("x_hot", type))
197 if (!strcmp("y_hot", type))
203 if (sscanf(line, "static short %s = {", name_and_type) == 1)
205 else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1)
207 else if (sscanf(line, "static char %s = {", name_and_type) == 1)
212 if (!(type = strrchr(name_and_type, '_')))
213 type = name_and_type;
217 if (strcmp("bits[]", type))
221 RETURN (BitmapFileInvalid);
223 if ((ww % 16) && ((ww % 16) < 9) && version10p)
228 bytes_per_line = (ww+7)/8 + padding;
230 size = bytes_per_line * hh;
231 bits = (unsigned char *) Xmalloc ((unsigned int) size);
233 RETURN (BitmapNoMemory);
239 for (bytes=0, ptr=bits; bytes<size; (bytes += 2)) {
240 if ((value = NextInt(fstream)) < 0)
241 RETURN (BitmapFileInvalid);
243 if (!padding || ((bytes+2) % bytes_per_line))
244 *(ptr++) = value >> 8;
250 for (bytes=0, ptr=bits; bytes<size; bytes++, ptr++) {
251 if ((value = NextInt(fstream)) < 0)
252 RETURN (BitmapFileInvalid);
259 return (BitmapFileInvalid);
264 if (x_hot) *x_hot = hx;
265 if (y_hot) *y_hot = hy;
267 return (BitmapSuccess);
270 #if NeedFunctionPrototypes
271 int _DtGrReadBitmapStream (
275 unsigned int *width, /* RETURNED */
276 unsigned int *height, /* RETURNED */
277 Pixmap *pixmap, /* RETURNED */
278 int *x_hot, /* RETURNED */
279 int *y_hot) /* RETURNED */
281 int _DtGrReadBitmapStream (display, d, stream, width, height, pixmap, x_hot, y_hot)
286 unsigned int *width, *height; /* RETURNED */
287 Pixmap *pixmap; /* RETURNED */
288 int *x_hot, *y_hot; /* RETURNED */
291 Pixmap pix; /* value to return */
295 res = _DtGrReadBitmapStreamData(stream, width, height, &data, x_hot, y_hot);
296 if (res != BitmapSuccess)
298 *pixmap = XCreateBitmapFromData(display, d, (char *)data, *width, *height);
301 return (BitmapNoMemory);
302 return (BitmapSuccess);