1
/* $Xorg: RdBitF.c,v 1.5 2001/02/09 02:03:35 xorgcvs Exp $ */
4
Copyright 1987, 1998 The Open Group
6
Permission to use, copy, modify, distribute, and sell this software and its
7
documentation for any purpose is hereby granted without fee, provided that
8
the above copyright notice appear in all copies and that both that
9
copyright notice and this permission notice appear in supporting
12
The above copyright notice and this permission notice shall be included
13
in all copies or substantial portions of the Software.
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
19
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21
OTHER DEALINGS IN THE SOFTWARE.
23
Except as contained in this notice, the name of The Open Group shall
24
not be used in advertising or otherwise to promote the sale, use or
25
other dealings in this Software without prior written authorization
29
/* $XFree86: xc/lib/X11/RdBitF.c,v 3.5 2002/05/31 18:45:41 dawes Exp $ */
32
* Code to read bitmaps from disk files. Interprets
33
* data from X10 and X11 bitmap files and creates
34
* Pixmap representations of files. Returns Pixmap
35
* ID and specifics about image.
37
* Modified for speedup by Jim Becker, changed image
38
* data parsing logic (removed some fscanf()s).
41
* Note that this file and ../Xmu/RdBitF.c look very similar.... Keep them
42
* that way (but don't use common source code so that people can have one
55
/* shared data for the image read/parse logic */
56
static short hexTable[256]; /* conversion value */
57
static Bool initialized = False; /* easier to fill in at run time */
61
* Table index for the hex values. Initialized once, first time.
62
* Used for translation value or delimiter significance lookup.
64
static void initHexTable()
67
* We build the table at run time for several reasons:
69
* 1. portable to non-ASCII machines.
70
* 2. still reentrant since we set the init flag after setting table.
71
* 3. easier to extend.
72
* 4. less prone to bugs.
74
hexTable['0'] = 0; hexTable['1'] = 1;
75
hexTable['2'] = 2; hexTable['3'] = 3;
76
hexTable['4'] = 4; hexTable['5'] = 5;
77
hexTable['6'] = 6; hexTable['7'] = 7;
78
hexTable['8'] = 8; hexTable['9'] = 9;
79
hexTable['A'] = 10; hexTable['B'] = 11;
80
hexTable['C'] = 12; hexTable['D'] = 13;
81
hexTable['E'] = 14; hexTable['F'] = 15;
82
hexTable['a'] = 10; hexTable['b'] = 11;
83
hexTable['c'] = 12; hexTable['d'] = 13;
84
hexTable['e'] = 14; hexTable['f'] = 15;
86
/* delimiters of significance are flagged w/ negative value */
87
hexTable[' '] = -1; hexTable[','] = -1;
88
hexTable['}'] = -1; hexTable['\n'] = -1;
95
* read next hex value in the input stream, return -1 if EOF
106
/* loop, accumulate hex value until find delimiter */
107
/* skip any initial delimiters found in read stream */
115
/* trim high bits, check type and accumulate */
117
if (isascii(ch) && isxdigit(ch)) {
118
value = (value << 4) + hexTable[ch];
120
} else if ((hexTable[ch]) < 0 && gotone)
127
#if NeedFunctionPrototypes
128
int XReadBitmapFileData (
129
_Xconst char *filename,
130
unsigned int *width, /* RETURNED */
131
unsigned int *height, /* RETURNED */
132
unsigned char **data, /* RETURNED */
133
int *x_hot, /* RETURNED */
134
int *y_hot) /* RETURNED */
136
int XReadBitmapFileData (filename, width, height, data, x_hot, y_hot)
138
unsigned int *width, *height; /* RETURNED */
139
unsigned char **data; /* RETURNED */
140
int *x_hot, *y_hot; /* RETURNED */
143
FILE *fstream; /* handle on file */
144
unsigned char *bits = NULL; /* working variable */
145
char line[MAX_SIZE]; /* input line from file */
146
int size; /* number of bytes of data */
147
char name_and_type[MAX_SIZE]; /* an input line */
148
char *type; /* for parsing */
149
int value; /* from an input line */
150
int version10p; /* boolean, old format */
151
int padding; /* to handle alignment */
152
int bytes_per_line; /* per scanline of data */
153
unsigned int ww = 0; /* width */
154
unsigned int hh = 0; /* height */
155
int hx = -1; /* x hotspot */
156
int hy = -1; /* y hotspot */
158
/* first time initialization */
159
if (initialized == False) initHexTable();
162
filename = __XOS2RedirRoot(filename);
164
if (!(fstream = fopen(filename, "r")))
165
return BitmapOpenFailed;
167
/* error cleanup and return macro */
168
#define RETURN(code) \
169
{ if (bits) Xfree ((char *)bits); fclose (fstream); return code; }
171
while (fgets(line, MAX_SIZE, fstream)) {
172
if (strlen(line) == MAX_SIZE-1)
173
RETURN (BitmapFileInvalid);
174
if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) {
175
if (!(type = strrchr(name_and_type, '_')))
176
type = name_and_type;
180
if (!strcmp("width", type))
181
ww = (unsigned int) value;
182
if (!strcmp("height", type))
183
hh = (unsigned int) value;
184
if (!strcmp("hot", type)) {
185
if (type-- == name_and_type || type-- == name_and_type)
187
if (!strcmp("x_hot", type))
189
if (!strcmp("y_hot", type))
195
if (sscanf(line, "static short %s = {", name_and_type) == 1)
197
else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1)
199
else if (sscanf(line, "static char %s = {", name_and_type) == 1)
204
if (!(type = strrchr(name_and_type, '_')))
205
type = name_and_type;
209
if (strcmp("bits[]", type))
213
RETURN (BitmapFileInvalid);
215
if ((ww % 16) && ((ww % 16) < 9) && version10p)
220
bytes_per_line = (ww+7)/8 + padding;
222
size = bytes_per_line * hh;
223
bits = (unsigned char *) Xmalloc ((unsigned int) size);
225
RETURN (BitmapNoMemory);
231
for (bytes=0, ptr=bits; bytes<size; (bytes += 2)) {
232
if ((value = NextInt(fstream)) < 0)
233
RETURN (BitmapFileInvalid);
235
if (!padding || ((bytes+2) % bytes_per_line))
236
*(ptr++) = value >> 8;
242
for (bytes=0, ptr=bits; bytes<size; bytes++, ptr++) {
243
if ((value = NextInt(fstream)) < 0)
244
RETURN (BitmapFileInvalid);
252
return (BitmapFileInvalid);
257
if (x_hot) *x_hot = hx;
258
if (y_hot) *y_hot = hy;
260
return (BitmapSuccess);
263
#if NeedFunctionPrototypes
264
int XReadBitmapFile (
267
_Xconst char *filename,
268
unsigned int *width, /* RETURNED */
269
unsigned int *height, /* RETURNED */
270
Pixmap *pixmap, /* RETURNED */
271
int *x_hot, /* RETURNED */
272
int *y_hot) /* RETURNED */
274
int XReadBitmapFile (display, d, filename, width, height, pixmap, x_hot, y_hot)
278
unsigned int *width, *height; /* RETURNED */
279
Pixmap *pixmap; /* RETURNED */
280
int *x_hot, *y_hot; /* RETURNED */
286
res = XReadBitmapFileData(filename, width, height, &data, x_hot, y_hot);
287
if (res != BitmapSuccess)
289
*pixmap = XCreateBitmapFromData(display, d, (char *)data, *width, *height);
292
return (BitmapNoMemory);
293
return (BitmapSuccess);