XbmUtils.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  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)
  10. * any later version.
  11. *
  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
  16. * details.
  17. *
  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
  22. */
  23. /* $XConsortium: XbmUtils.c /main/4 1996/05/09 03:44:48 drk $ */
  24. /*
  25. ** XbmUtils.c
  26. **
  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.
  30. */
  31. /*
  32. Copyright (c) 1987 X Consortium
  33. Permission is hereby granted, free of charge, to any person obtaining
  34. a copy of this software and associated documentation files (the
  35. "Software"), to deal in the Software without restriction, including
  36. without limitation the rights to use, copy, modify, merge, publish,
  37. distribute, sublicense, and/or sell copies of the Software, and to
  38. permit persons to whom the Software is furnished to do so, subject to
  39. the following conditions:
  40. The above copyright notice and this permission notice shall be included
  41. in all copies or substantial portions of the Software.
  42. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  43. OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  44. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  45. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
  46. OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  47. ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  48. OTHER DEALINGS IN THE SOFTWARE.
  49. Except as contained in this notice, the name of the X Consortium shall
  50. not be used in advertising or otherwise to promote the sale, use or
  51. other dealings in this Software without prior written authorization
  52. from the X Consortium.
  53. */
  54. /*
  55. * Code to read bitmaps from disk files. Interprets
  56. * data from X10 and X11 bitmap files and creates
  57. * Pixmap representations of files. Returns Pixmap
  58. * ID and specifics about image.
  59. *
  60. * Modified for speedup by Jim Becker, changed image
  61. * data parsing logic (removed some fscanf()s).
  62. * Aug 5, 1988
  63. *
  64. * Note that this file and ../Xmu/RdBitF.c look very similar.... Keep them
  65. * that way (but don't use common source code so that people can have one
  66. * without the other).
  67. */
  68. #include <X11/IntrinsicP.h>
  69. #include <X11/Xlibint.h>
  70. #include <X11/Xos.h>
  71. #include <X11/Xutil.h>
  72. #include <stdio.h>
  73. #include <ctype.h>
  74. #include "GraphicsP.h"
  75. #include "Lock.h"
  76. #define MAX_SIZE 255
  77. /* shared data for the image read/parse logic */
  78. static short hexTable[256]; /* conversion value */
  79. /*
  80. * Table index for the hex values. Initialized once, first time.
  81. * Used for translation value or delimiter significance lookup.
  82. */
  83. static void initHexTable(void)
  84. {
  85. /*
  86. * We build the table at run time for several reasons:
  87. *
  88. * 1. portable to non-ASCII machines.
  89. * 2. still reentrant since we set the init flag after setting table.
  90. * 3. easier to extend.
  91. * 4. less prone to bugs.
  92. */
  93. hexTable['0'] = 0; hexTable['1'] = 1;
  94. hexTable['2'] = 2; hexTable['3'] = 3;
  95. hexTable['4'] = 4; hexTable['5'] = 5;
  96. hexTable['6'] = 6; hexTable['7'] = 7;
  97. hexTable['8'] = 8; hexTable['9'] = 9;
  98. hexTable['A'] = 10; hexTable['B'] = 11;
  99. hexTable['C'] = 12; hexTable['D'] = 13;
  100. hexTable['E'] = 14; hexTable['F'] = 15;
  101. hexTable['a'] = 10; hexTable['b'] = 11;
  102. hexTable['c'] = 12; hexTable['d'] = 13;
  103. hexTable['e'] = 14; hexTable['f'] = 15;
  104. /* delimiters of significance are flagged w/ negative value */
  105. hexTable[' '] = -1; hexTable[','] = -1;
  106. hexTable['}'] = -1; hexTable['\n'] = -1;
  107. hexTable['\t'] = -1;
  108. }
  109. /*
  110. * read next hex value in the input stream, return -1 if EOF
  111. */
  112. static int NextInt (_DtGrStream *fstream)
  113. {
  114. int ch;
  115. int value = 0;
  116. int gotone = 0;
  117. int done = 0;
  118. /* loop, accumulate hex value until find delimiter */
  119. /* skip any initial delimiters found in read stream */
  120. _DtHelpProcessLock();
  121. while (!done) {
  122. ch = _DtGrGetChar(fstream);
  123. if (ch == EOF) {
  124. value = -1;
  125. done++;
  126. } else {
  127. /* trim high bits, check type and accumulate */
  128. ch &= 0xff;
  129. if (isascii(ch) && isxdigit(ch)) {
  130. value = (value << 4) + hexTable[ch];
  131. gotone++;
  132. } else if ((hexTable[ch]) < 0 && gotone)
  133. done++;
  134. }
  135. }
  136. _DtHelpProcessUnlock();
  137. return value;
  138. }
  139. #if NeedFunctionPrototypes
  140. int _DtGrReadBitmapStreamData (
  141. _DtGrStream *fstream,
  142. unsigned int *width, /* RETURNED */
  143. unsigned int *height, /* RETURNED */
  144. unsigned char **data, /* RETURNED */
  145. int *x_hot, /* RETURNED */
  146. int *y_hot) /* RETURNED */
  147. #else
  148. int _DtGrReadBitmapStreamData (stream, width, height, data, x_hot, y_hot)
  149. _DtGrStream *fstream;
  150. unsigned int *width, *height; /* RETURNED */
  151. unsigned char **data; /* RETURNED */
  152. int *x_hot, *y_hot; /* RETURNED */
  153. #endif
  154. {
  155. unsigned char *bits = NULL; /* working variable */
  156. char line[MAX_SIZE]; /* input line from file */
  157. int size; /* number of bytes of data */
  158. char name_and_type[MAX_SIZE]; /* an input line */
  159. char *type; /* for parsing */
  160. int value; /* from an input line */
  161. int version10p; /* boolean, old format */
  162. int padding; /* to handle alignment */
  163. int bytes_per_line; /* per scanline of data */
  164. unsigned int ww = 0; /* width */
  165. unsigned int hh = 0; /* height */
  166. int hx = -1; /* x hotspot */
  167. int hy = -1; /* y hotspot */
  168. static Bool initialized = False; /* easier to fill in at run time */
  169. /* first time initialization */
  170. _DtHelpProcessLock();
  171. if (initialized == False)
  172. {
  173. initHexTable();
  174. initialized = True;
  175. }
  176. _DtHelpProcessUnlock();
  177. /* error cleanup and return macro */
  178. #define RETURN(code) \
  179. { if (bits) Xfree ((char *)bits); return code; }
  180. while (_DtGrGetString(line, MAX_SIZE, fstream)) {
  181. if (strlen(line) == MAX_SIZE-1)
  182. RETURN (BitmapFileInvalid);
  183. if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) {
  184. if (!(type = strrchr(name_and_type, '_')))
  185. type = name_and_type;
  186. else
  187. 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)
  194. continue;
  195. if (!strcmp("x_hot", type))
  196. hx = value;
  197. if (!strcmp("y_hot", type))
  198. hy = value;
  199. }
  200. continue;
  201. }
  202. if (sscanf(line, "static short %s = {", name_and_type) == 1)
  203. version10p = 1;
  204. else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1)
  205. version10p = 0;
  206. else if (sscanf(line, "static char %s = {", name_and_type) == 1)
  207. version10p = 0;
  208. else
  209. continue;
  210. if (!(type = strrchr(name_and_type, '_')))
  211. type = name_and_type;
  212. else
  213. type++;
  214. if (strcmp("bits[]", type))
  215. continue;
  216. if (!ww || !hh)
  217. RETURN (BitmapFileInvalid);
  218. if ((ww % 16) && ((ww % 16) < 9) && version10p)
  219. padding = 1;
  220. else
  221. padding = 0;
  222. bytes_per_line = (ww+7)/8 + padding;
  223. size = bytes_per_line * hh;
  224. bits = (unsigned char *) Xmalloc ((unsigned int) size);
  225. if (!bits)
  226. RETURN (BitmapNoMemory);
  227. if (version10p) {
  228. unsigned char *ptr;
  229. int bytes;
  230. for (bytes=0, ptr=bits; bytes<size; (bytes += 2)) {
  231. if ((value = NextInt(fstream)) < 0)
  232. RETURN (BitmapFileInvalid);
  233. *(ptr++) = value;
  234. if (!padding || ((bytes+2) % bytes_per_line))
  235. *(ptr++) = value >> 8;
  236. }
  237. } else {
  238. unsigned char *ptr;
  239. int bytes;
  240. for (bytes=0, ptr=bits; bytes<size; bytes++, ptr++) {
  241. if ((value = NextInt(fstream)) < 0)
  242. RETURN (BitmapFileInvalid);
  243. *ptr=value;
  244. }
  245. }
  246. } /* end while */
  247. if (!bits)
  248. return (BitmapFileInvalid);
  249. *data = bits;
  250. *width = ww;
  251. *height = hh;
  252. if (x_hot) *x_hot = hx;
  253. if (y_hot) *y_hot = hy;
  254. return (BitmapSuccess);
  255. }
  256. #if NeedFunctionPrototypes
  257. int _DtGrReadBitmapStream (
  258. Display *display,
  259. Drawable d,
  260. _DtGrStream *stream,
  261. unsigned int *width, /* RETURNED */
  262. unsigned int *height, /* RETURNED */
  263. Pixmap *pixmap, /* RETURNED */
  264. int *x_hot, /* RETURNED */
  265. int *y_hot) /* RETURNED */
  266. #else
  267. int _DtGrReadBitmapStream (display, d, stream, width, height, pixmap, x_hot, y_hot)
  268. Display *display;
  269. Drawable d;
  270. _DtGrStream *stream;
  271. char *filename;
  272. unsigned int *width, *height; /* RETURNED */
  273. Pixmap *pixmap; /* RETURNED */
  274. int *x_hot, *y_hot; /* RETURNED */
  275. #endif
  276. {
  277. unsigned char *data;
  278. int res;
  279. res = _DtGrReadBitmapStreamData(stream, width, height, &data, x_hot, y_hot);
  280. if (res != BitmapSuccess)
  281. return res;
  282. *pixmap = XCreateBitmapFromData(display, d, (char *)data, *width, *height);
  283. Xfree((char *)data);
  284. if (*pixmap == None)
  285. return (BitmapNoMemory);
  286. return (BitmapSuccess);
  287. }