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 librararies 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()
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 (fstream)
128 _DtGrStream *fstream;
135 /* loop, accumulate hex value until find delimiter */
136 /* skip any initial delimiters found in read stream */
138 _DtHelpProcessLock();
140 ch = _DtGrGetChar(fstream);
145 /* trim high bits, check type and accumulate */
147 if (isascii(ch) && isxdigit(ch)) {
148 value = (value << 4) + hexTable[ch];
150 } else if ((hexTable[ch]) < 0 && gotone)
154 _DtHelpProcessUnlock();
158 #if NeedFunctionPrototypes
159 int _DtGrReadBitmapStreamData (
160 _DtGrStream *fstream,
161 unsigned int *width, /* RETURNED */
162 unsigned int *height, /* RETURNED */
163 unsigned char **data, /* RETURNED */
164 int *x_hot, /* RETURNED */
165 int *y_hot) /* RETURNED */
167 int _DtGrReadBitmapStreamData (stream, width, height, data, x_hot, y_hot)
168 _DtGrStream *fstream;
169 unsigned int *width, *height; /* RETURNED */
170 unsigned char **data; /* RETURNED */
171 int *x_hot, *y_hot; /* RETURNED */
174 unsigned char *bits = NULL; /* working variable */
175 char line[MAX_SIZE]; /* input line from file */
176 int size; /* number of bytes of data */
177 char name_and_type[MAX_SIZE]; /* an input line */
178 char *type; /* for parsing */
179 int value; /* from an input line */
180 int version10p; /* boolean, old format */
181 int padding; /* to handle alignment */
182 int bytes_per_line; /* per scanline of data */
183 unsigned int ww = 0; /* width */
184 unsigned int hh = 0; /* height */
185 int hx = -1; /* x hotspot */
186 int hy = -1; /* y hotspot */
187 static Bool initialized = False; /* easier to fill in at run time */
189 /* first time initialization */
190 _DtHelpProcessLock();
191 if (initialized == False)
196 _DtHelpProcessUnlock();
198 /* error cleanup and return macro */
199 #define RETURN(code) \
200 { if (bits) Xfree ((char *)bits); return code; }
202 while (_DtGrGetString(line, MAX_SIZE, fstream)) {
203 if (strlen(line) == MAX_SIZE-1)
204 RETURN (BitmapFileInvalid);
205 if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) {
206 if (!(type = strrchr(name_and_type, '_')))
207 type = name_and_type;
211 if (!strcmp("width", type))
212 ww = (unsigned int) value;
213 if (!strcmp("height", type))
214 hh = (unsigned int) value;
215 if (!strcmp("hot", type)) {
216 if (type-- == name_and_type || type-- == name_and_type)
218 if (!strcmp("x_hot", type))
220 if (!strcmp("y_hot", type))
226 if (sscanf(line, "static short %s = {", name_and_type) == 1)
228 else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1)
230 else if (sscanf(line, "static char %s = {", name_and_type) == 1)
235 if (!(type = strrchr(name_and_type, '_')))
236 type = name_and_type;
240 if (strcmp("bits[]", type))
244 RETURN (BitmapFileInvalid);
246 if ((ww % 16) && ((ww % 16) < 9) && version10p)
251 bytes_per_line = (ww+7)/8 + padding;
253 size = bytes_per_line * hh;
254 bits = (unsigned char *) Xmalloc ((unsigned int) size);
256 RETURN (BitmapNoMemory);
262 for (bytes=0, ptr=bits; bytes<size; (bytes += 2)) {
263 if ((value = NextInt(fstream)) < 0)
264 RETURN (BitmapFileInvalid);
266 if (!padding || ((bytes+2) % bytes_per_line))
267 *(ptr++) = value >> 8;
273 for (bytes=0, ptr=bits; bytes<size; bytes++, ptr++) {
274 if ((value = NextInt(fstream)) < 0)
275 RETURN (BitmapFileInvalid);
282 return (BitmapFileInvalid);
287 if (x_hot) *x_hot = hx;
288 if (y_hot) *y_hot = hy;
290 return (BitmapSuccess);
293 #if NeedFunctionPrototypes
294 int _DtGrReadBitmapStream (
298 unsigned int *width, /* RETURNED */
299 unsigned int *height, /* RETURNED */
300 Pixmap *pixmap, /* RETURNED */
301 int *x_hot, /* RETURNED */
302 int *y_hot) /* RETURNED */
304 int _DtGrReadBitmapStream (display, d, stream, width, height, pixmap, x_hot, y_hot)
309 unsigned int *width, *height; /* RETURNED */
310 Pixmap *pixmap; /* RETURNED */
311 int *x_hot, *y_hot; /* RETURNED */
317 res = _DtGrReadBitmapStreamData(stream, width, height, &data, x_hot, y_hot);
318 if (res != BitmapSuccess)
320 *pixmap = XCreateBitmapFromData(display, d, (char *)data, *width, *height);
323 return (BitmapNoMemory);
324 return (BitmapSuccess);