PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/src/RdFToI.c

#
C | 273 lines | 206 code | 20 blank | 47 comment | 40 complexity | 644f80994afd701998b7c7f5811a677b MD5 | raw file
  1. /*
  2. * Copyright (C) 1989-95 GROUPE BULL
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to
  6. * deal in the Software without restriction, including without limitation the
  7. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. * sell copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  18. * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  20. *
  21. * Except as contained in this notice, the name of GROUPE BULL shall not be
  22. * used in advertising or otherwise to promote the sale, use or other dealings
  23. * in this Software without prior written authorization from GROUPE BULL.
  24. */
  25. /*****************************************************************************\
  26. * RdFToI.c: *
  27. * *
  28. * XPM library *
  29. * Parse an XPM file and create the image and possibly its mask *
  30. * *
  31. * Developed by Arnaud Le Hors *
  32. \*****************************************************************************/
  33. /* October 2004, source code review by Thomas Biege <thomas@suse.de> */
  34. #ifdef HAVE_CONFIG_H
  35. #include <config.h>
  36. #endif
  37. #include "XpmI.h"
  38. #ifndef NO_ZPIPE
  39. #include <fcntl.h>
  40. #include <errno.h>
  41. #include <sys/types.h>
  42. #include <sys/wait.h>
  43. #else
  44. #ifdef FOR_MSW
  45. #include <fcntl.h>
  46. #endif
  47. #endif
  48. LFUNC(OpenReadFile, int, (char *filename, xpmData *mdata));
  49. LFUNC(xpmDataClose, void, (xpmData *mdata));
  50. FUNC(xpmPipeThrough, FILE*, (int fd,
  51. const char *cmd,
  52. const char *arg1,
  53. const char *mode));
  54. #ifndef CXPMPROG
  55. int
  56. XpmReadFileToImage(
  57. Display *display,
  58. char *filename,
  59. XImage **image_return,
  60. XImage **shapeimage_return,
  61. XpmAttributes *attributes)
  62. {
  63. XpmImage image;
  64. XpmInfo info;
  65. int ErrorStatus;
  66. xpmData mdata;
  67. xpmInitXpmImage(&image);
  68. xpmInitXpmInfo(&info);
  69. /* open file to read */
  70. if ((ErrorStatus = OpenReadFile(filename, &mdata)) != XpmSuccess)
  71. return (ErrorStatus);
  72. /* create the XImage from the XpmData */
  73. if (attributes) {
  74. xpmInitAttributes(attributes);
  75. xpmSetInfoMask(&info, attributes);
  76. ErrorStatus = xpmParseDataAndCreate(display, &mdata,
  77. image_return, shapeimage_return,
  78. &image, &info, attributes);
  79. } else
  80. ErrorStatus = xpmParseDataAndCreate(display, &mdata,
  81. image_return, shapeimage_return,
  82. &image, NULL, attributes);
  83. if (attributes) {
  84. if (ErrorStatus >= 0) /* no fatal error */
  85. xpmSetAttributes(attributes, &image, &info);
  86. XpmFreeXpmInfo(&info);
  87. }
  88. xpmDataClose(&mdata);
  89. /* free the XpmImage */
  90. XpmFreeXpmImage(&image);
  91. return (ErrorStatus);
  92. }
  93. int
  94. XpmReadFileToXpmImage(
  95. char *filename,
  96. XpmImage *image,
  97. XpmInfo *info)
  98. {
  99. xpmData mdata;
  100. int ErrorStatus;
  101. /* init returned values */
  102. xpmInitXpmImage(image);
  103. xpmInitXpmInfo(info);
  104. /* open file to read */
  105. if ((ErrorStatus = OpenReadFile(filename, &mdata)) != XpmSuccess)
  106. return (ErrorStatus);
  107. /* create the XpmImage from the XpmData */
  108. ErrorStatus = xpmParseData(&mdata, image, info);
  109. xpmDataClose(&mdata);
  110. return (ErrorStatus);
  111. }
  112. #endif /* CXPMPROG */
  113. #ifndef NO_ZPIPE
  114. /* Do not depend on errno after read_through */
  115. FILE*
  116. xpmPipeThrough(
  117. int fd,
  118. const char *cmd,
  119. const char *arg1,
  120. const char *mode)
  121. {
  122. FILE* fp;
  123. int status, fds[2], in = 0, out = 1;
  124. pid_t pid;
  125. if ( 'w' == *mode )
  126. out = 0, in = 1;
  127. if ( pipe(fds) < 0 )
  128. return NULL;
  129. pid = fork();
  130. if ( pid < 0 )
  131. goto fail1;
  132. if ( 0 == pid )
  133. {
  134. close(fds[in]);
  135. if ( dup2(fds[out], out) < 0 )
  136. goto err;
  137. close(fds[out]);
  138. if ( dup2(fd, in) < 0 )
  139. goto err;
  140. close(fd);
  141. pid = fork();
  142. if ( pid < 0 )
  143. goto err;
  144. if ( 0 == pid )
  145. {
  146. execlp(cmd, cmd, arg1, (char *)NULL);
  147. perror(cmd);
  148. goto err;
  149. }
  150. _exit(0);
  151. err:
  152. _exit(1);
  153. }
  154. close(fds[out]);
  155. /* calling process: wait for first child */
  156. while ( waitpid(pid, &status, 0) < 0 && EINTR == errno )
  157. ;
  158. if ( WIFSIGNALED(status) ||
  159. (WIFEXITED(status) && WEXITSTATUS(status) != 0) )
  160. goto fail2;
  161. fp = fdopen(fds[in], mode);
  162. if ( !fp )
  163. goto fail2;
  164. close(fd); /* still open in 2nd child */
  165. return fp;
  166. fail1:
  167. close(fds[out]);
  168. fail2:
  169. close(fds[in]);
  170. return NULL;
  171. }
  172. #endif
  173. /*
  174. * open the given file to be read as an xpmData which is returned.
  175. */
  176. static int
  177. OpenReadFile(
  178. char *filename,
  179. xpmData *mdata)
  180. {
  181. if (!filename) {
  182. mdata->stream.file = (stdin);
  183. mdata->type = XPMFILE;
  184. } else {
  185. int fd = open(filename, O_RDONLY);
  186. #if defined(NO_ZPIPE)
  187. if ( fd < 0 )
  188. return XpmOpenFailed;
  189. #else
  190. const char* ext = NULL;
  191. if ( fd >= 0 )
  192. ext = strrchr(filename, '.');
  193. #ifdef STAT_ZFILE /* searching for z-files if the given name not found */
  194. else
  195. {
  196. size_t len = strlen(filename);
  197. char *compressfile = (char *) XpmMalloc(len + 4);
  198. if ( !compressfile )
  199. return (XpmNoMemory);
  200. strcpy(compressfile, filename);
  201. strcpy(compressfile + len, ext = ".Z");
  202. fd = open(compressfile, O_RDONLY);
  203. if ( fd < 0 )
  204. {
  205. strcpy(compressfile + len, ext = ".gz");
  206. fd = open(compressfile, O_RDONLY);
  207. if ( fd < 0 )
  208. {
  209. XpmFree(compressfile);
  210. return XpmOpenFailed;
  211. }
  212. }
  213. XpmFree(compressfile);
  214. }
  215. #endif
  216. if ( ext && !strcmp(ext, ".Z") )
  217. {
  218. mdata->type = XPMPIPE;
  219. mdata->stream.file = xpmPipeThrough(fd, "uncompress", "-c", "r");
  220. }
  221. else if ( ext && !strcmp(ext, ".gz") )
  222. {
  223. mdata->type = XPMPIPE;
  224. mdata->stream.file = xpmPipeThrough(fd, "gunzip", "-qc", "r");
  225. }
  226. else
  227. #endif /* z-files */
  228. {
  229. mdata->type = XPMFILE;
  230. mdata->stream.file = fdopen(fd, "r");
  231. }
  232. if (!mdata->stream.file)
  233. {
  234. close(fd);
  235. return (XpmOpenFailed);
  236. }
  237. }
  238. mdata->CommentLength = 0;
  239. #ifdef CXPMPROG
  240. mdata->lineNum = 0;
  241. mdata->charNum = 0;
  242. #endif
  243. return (XpmSuccess);
  244. }
  245. /*
  246. * close the file related to the xpmData if any
  247. */
  248. static void
  249. xpmDataClose(xpmData *mdata)
  250. {
  251. if (mdata->stream.file != (stdin))
  252. fclose(mdata->stream.file);
  253. }