2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: XbmUtils.c /main/4 1996/05/09 03:44:48 drk $ */
27 ** This module provides routines that allow a pixmap to be generated from
28 ** a _DtGrStream containing XBM data. The module is adapted from the
29 ** RdBitF.c module in the X11R6 version of libX11.
34 Copyright (c) 1987 X Consortium
36 Permission is hereby granted, free of charge, to any person obtaining
37 a copy of this software and associated documentation files (the
38 "Software"), to deal in the Software without restriction, including
39 without limitation the rights to use, copy, modify, merge, publish,
40 distribute, sublicense, and/or sell copies of the Software, and to
41 permit persons to whom the Software is furnished to do so, subject to
42 the following conditions:
44 The above copyright notice and this permission notice shall be included
45 in all copies or substantial portions of the Software.
47 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
48 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
49 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
50 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
51 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
52 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
53 OTHER DEALINGS IN THE SOFTWARE.
55 Except as contained in this notice, the name of the X Consortium shall
56 not be used in advertising or otherwise to promote the sale, use or
57 other dealings in this Software without prior written authorization
58 from the X Consortium.
63 * Code to read bitmaps from disk files. Interprets
64 * data from X10 and X11 bitmap files and creates
65 * Pixmap representations of files. Returns Pixmap
66 * ID and specifics about image.
68 * Modified for speedup by Jim Becker, changed image
69 * data parsing logic (removed some fscanf()s).
72 * Note that this file and ../Xmu/RdBitF.c look very similar.... Keep them
73 * that way (but don't use common source code so that people can have one
77 #include <X11/IntrinsicP.h>
78 #include <X11/Xlibint.h>
80 #include <X11/Xutil.h>
84 #include "GraphicsP.h"
89 /* shared data for the image read/parse logic */
90 static short hexTable[256]; /* conversion value */
93 * Table index for the hex values. Initialized once, first time.
94 * Used for translation value or delimiter significance lookup.
96 static void initHexTable(void)
99 * We build the table at run time for several reasons:
101 * 1. portable to non-ASCII machines.
102 * 2. still reentrant since we set the init flag after setting table.
103 * 3. easier to extend.
104 * 4. less prone to bugs.
106 hexTable['0'] = 0; hexTable['1'] = 1;
107 hexTable['2'] = 2; hexTable['3'] = 3;
108 hexTable['4'] = 4; hexTable['5'] = 5;
109 hexTable['6'] = 6; hexTable['7'] = 7;
110 hexTable['8'] = 8; hexTable['9'] = 9;
111 hexTable['A'] = 10; hexTable['B'] = 11;
112 hexTable['C'] = 12; hexTable['D'] = 13;
113 hexTable['E'] = 14; hexTable['F'] = 15;
114 hexTable['a'] = 10; hexTable['b'] = 11;
115 hexTable['c'] = 12; hexTable['d'] = 13;
116 hexTable['e'] = 14; hexTable['f'] = 15;
118 /* delimiters of significance are flagged w/ negative value */
119 hexTable[' '] = -1; hexTable[','] = -1;
120 hexTable['}'] = -1; hexTable['\n'] = -1;
125 * read next hex value in the input stream, return -1 if EOF
127 static int NextInt (_DtGrStream *fstream)
134 /* loop, accumulate hex value until find delimiter */
135 /* skip any initial delimiters found in read stream */
137 _DtHelpProcessLock();
139 ch = _DtGrGetChar(fstream);
144 /* trim high bits, check type and accumulate */
146 if (isascii(ch) && isxdigit(ch)) {
147 value = (value << 4) + hexTable[ch];
149 } else if ((hexTable[ch]) < 0 && gotone)
153 _DtHelpProcessUnlock();
157 #if NeedFunctionPrototypes
158 int _DtGrReadBitmapStreamData (
159 _DtGrStream *fstream,
160 unsigned int *width, /* RETURNED */
161 unsigned int *height, /* RETURNED */
162 unsigned char **data, /* RETURNED */
163 int *x_hot, /* RETURNED */
164 int *y_hot) /* RETURNED */
166 int _DtGrReadBitmapStreamData (stream, width, height, data, x_hot, y_hot)
167 _DtGrStream *fstream;
168 unsigned int *width, *height; /* RETURNED */
169 unsigned char **data; /* RETURNED */
170 int *x_hot, *y_hot; /* RETURNED */
173 unsigned char *bits = NULL; /* working variable */
174 char line[MAX_SIZE]; /* input line from file */
175 int size; /* number of bytes of data */
176 char name_and_type[MAX_SIZE]; /* an input line */
177 char *type; /* for parsing */
178 int value; /* from an input line */
179 int version10p; /* boolean, old format */
180 int padding; /* to handle alignment */
181 int bytes_per_line; /* per scanline of data */
182 unsigned int ww = 0; /* width */
183 unsigned int hh = 0; /* height */
184 int hx = -1; /* x hotspot */
185 int hy = -1; /* y hotspot */
186 static Bool initialized = False; /* easier to fill in at run time */
188 /* first time initialization */
189 _DtHelpProcessLock();
190 if (initialized == False)
195 _DtHelpProcessUnlock();
197 /* error cleanup and return macro */
198 #define RETURN(code) \
199 { if (bits) Xfree ((char *)bits); return code; }
201 while (_DtGrGetString(line, MAX_SIZE, fstream)) {
202 if (strlen(line) == MAX_SIZE-1)
203 RETURN (BitmapFileInvalid);
204 if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) {
205 if (!(type = strrchr(name_and_type, '_')))
206 type = name_and_type;
210 if (!strcmp("width", type))
211 ww = (unsigned int) value;
212 if (!strcmp("height", type))
213 hh = (unsigned int) value;
214 if (!strcmp("hot", type)) {
215 if (type-- == name_and_type || type-- == name_and_type)
217 if (!strcmp("x_hot", type))
219 if (!strcmp("y_hot", type))
225 if (sscanf(line, "static short %s = {", name_and_type) == 1)
227 else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1)
229 else if (sscanf(line, "static char %s = {", name_and_type) == 1)
234 if (!(type = strrchr(name_and_type, '_')))
235 type = name_and_type;
239 if (strcmp("bits[]", type))
243 RETURN (BitmapFileInvalid);
245 if ((ww % 16) && ((ww % 16) < 9) && version10p)
250 bytes_per_line = (ww+7)/8 + padding;
252 size = bytes_per_line * hh;
253 bits = (unsigned char *) Xmalloc ((unsigned int) size);
255 RETURN (BitmapNoMemory);
261 for (bytes=0, ptr=bits; bytes<size; (bytes += 2)) {
262 if ((value = NextInt(fstream)) < 0)
263 RETURN (BitmapFileInvalid);
265 if (!padding || ((bytes+2) % bytes_per_line))
266 *(ptr++) = value >> 8;
272 for (bytes=0, ptr=bits; bytes<size; bytes++, ptr++) {
273 if ((value = NextInt(fstream)) < 0)
274 RETURN (BitmapFileInvalid);
281 return (BitmapFileInvalid);
286 if (x_hot) *x_hot = hx;
287 if (y_hot) *y_hot = hy;
289 return (BitmapSuccess);
292 #if NeedFunctionPrototypes
293 int _DtGrReadBitmapStream (
297 unsigned int *width, /* RETURNED */
298 unsigned int *height, /* RETURNED */
299 Pixmap *pixmap, /* RETURNED */
300 int *x_hot, /* RETURNED */
301 int *y_hot) /* RETURNED */
303 int _DtGrReadBitmapStream (display, d, stream, width, height, pixmap, x_hot, y_hot)
308 unsigned int *width, *height; /* RETURNED */
309 Pixmap *pixmap; /* RETURNED */
310 int *x_hot, *y_hot; /* RETURNED */
316 res = _DtGrReadBitmapStreamData(stream, width, height, &data, x_hot, y_hot);
317 if (res != BitmapSuccess)
319 *pixmap = XCreateBitmapFromData(display, d, (char *)data, *width, *height);
322 return (BitmapNoMemory);
323 return (BitmapSuccess);