/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/*****************************************************************************\ 27* RdFToI.c: * 28* * 29* XPM library * 30* Parse an XPM file and create the image and possibly its mask * 31* * 32* Developed by Arnaud Le Hors * 33\*****************************************************************************/ 34 35/* October 2004, source code review by Thomas Biege <thomas@suse.de> */ 36 37#ifdef HAVE_CONFIG_H 38#include <config.h> 39#endif 40#include "XpmI.h" 41#ifndef NO_ZPIPE 42#include <fcntl.h> 43#include <errno.h> 44#include <sys/types.h> 45#include <sys/wait.h> 46#else 47#ifdef FOR_MSW 48#include <fcntl.h> 49#endif 50#endif 51 52LFUNC(OpenReadFile, int, (char *filename, xpmData *mdata)); 53LFUNC(xpmDataClose, void, (xpmData *mdata)); 54 55FUNC(xpmPipeThrough, FILE*, (int fd, 56 const char *cmd, 57 const char *arg1, 58 const char *mode)); 59 60#ifndef CXPMPROG 61int 62XpmReadFileToImage( 63 Display *display, 64 char *filename, 65 XImage **image_return, 66 XImage **shapeimage_return, 67 XpmAttributes *attributes) 68{ 69 XpmImage image; 70 XpmInfo info; 71 int ErrorStatus; 72 xpmData mdata; 73 74 xpmInitXpmImage(&image); 75 xpmInitXpmInfo(&info); 76 77 /* open file to read */ 78 if ((ErrorStatus = OpenReadFile(filename, &mdata)) != XpmSuccess) 79 return (ErrorStatus); 80 81 /* create the XImage from the XpmData */ 82 if (attributes) { 83 xpmInitAttributes(attributes); 84 xpmSetInfoMask(&info, attributes); 85 ErrorStatus = xpmParseDataAndCreate(display, &mdata, 86 image_return, shapeimage_return, 87 &image, &info, attributes); 88 } else 89 ErrorStatus = xpmParseDataAndCreate(display, &mdata, 90 image_return, shapeimage_return, 91 &image, NULL, attributes); 92 if (attributes) { 93 if (ErrorStatus >= 0) /* no fatal error */ 94 xpmSetAttributes(attributes, &image, &info); 95 XpmFreeXpmInfo(&info); 96 } 97 98 xpmDataClose(&mdata); 99 /* free the XpmImage */ 100 XpmFreeXpmImage(&image); 101 102 return (ErrorStatus); 103} 104 105int 106XpmReadFileToXpmImage( 107 char *filename, 108 XpmImage *image, 109 XpmInfo *info) 110{ 111 xpmData mdata; 112 int ErrorStatus; 113 114 /* init returned values */ 115 xpmInitXpmImage(image); 116 xpmInitXpmInfo(info); 117 118 /* open file to read */ 119 if ((ErrorStatus = OpenReadFile(filename, &mdata)) != XpmSuccess) 120 return (ErrorStatus); 121 122 /* create the XpmImage from the XpmData */ 123 ErrorStatus = xpmParseData(&mdata, image, info); 124 125 xpmDataClose(&mdata); 126 127 return (ErrorStatus); 128} 129#endif /* CXPMPROG */ 130 131#ifndef NO_ZPIPE 132/* Do not depend on errno after read_through */ 133FILE* 134xpmPipeThrough( 135 int fd, 136 const char *cmd, 137 const char *arg1, 138 const char *mode) 139{ 140 FILE* fp; 141 int status, fds[2], in = 0, out = 1; 142 pid_t pid; 143 if ( 'w' == *mode ) 144 out = 0, in = 1; 145 if ( pipe(fds) < 0 ) 146 return NULL; 147 pid = fork(); 148 if ( pid < 0 ) 149 goto fail1; 150 if ( 0 == pid ) 151 { 152 close(fds[in]); 153 if ( dup2(fds[out], out) < 0 ) 154 goto err; 155 close(fds[out]); 156 if ( dup2(fd, in) < 0 ) 157 goto err; 158 close(fd); 159 pid = fork(); 160 if ( pid < 0 ) 161 goto err; 162 if ( 0 == pid ) 163 { 164 execlp(cmd, cmd, arg1, (char *)NULL); 165 perror(cmd); 166 goto err; 167 } 168 _exit(0); 169 err: 170 _exit(1); 171 } 172 close(fds[out]); 173 /* calling process: wait for first child */ 174 while ( waitpid(pid, &status, 0) < 0 && EINTR == errno ) 175 ; 176 if ( WIFSIGNALED(status) || 177 (WIFEXITED(status) && WEXITSTATUS(status) != 0) ) 178 goto fail2; 179 fp = fdopen(fds[in], mode); 180 if ( !fp ) 181 goto fail2; 182 close(fd); /* still open in 2nd child */ 183 return fp; 184fail1: 185 close(fds[out]); 186fail2: 187 close(fds[in]); 188 return NULL; 189} 190#endif 191 192/* 193 * open the given file to be read as an xpmData which is returned. 194 */ 195static int 196OpenReadFile( 197 char *filename, 198 xpmData *mdata) 199{ 200 if (!filename) { 201 mdata->stream.file = (stdin); 202 mdata->type = XPMFILE; 203 } else { 204 int fd = open(filename, O_RDONLY); 205#if defined(NO_ZPIPE) 206 if ( fd < 0 ) 207 return XpmOpenFailed; 208#else 209 const char* ext = NULL; 210 if ( fd >= 0 ) 211 ext = strrchr(filename, '.'); 212#ifdef STAT_ZFILE /* searching for z-files if the given name not found */ 213 else 214 { 215 size_t len = strlen(filename); 216 char *compressfile = (char *) XpmMalloc(len + 4); 217 if ( !compressfile ) 218 return (XpmNoMemory); 219 strcpy(compressfile, filename); 220 strcpy(compressfile + len, ext = ".Z"); 221 fd = open(compressfile, O_RDONLY); 222 if ( fd < 0 ) 223 { 224 strcpy(compressfile + len, ext = ".gz"); 225 fd = open(compressfile, O_RDONLY); 226 if ( fd < 0 ) 227 { 228 XpmFree(compressfile); 229 return XpmOpenFailed; 230 } 231 } 232 XpmFree(compressfile); 233 } 234#endif 235 if ( ext && !strcmp(ext, ".Z") ) 236 { 237 mdata->type = XPMPIPE; 238 mdata->stream.file = xpmPipeThrough(fd, "uncompress", "-c", "r"); 239 } 240 else if ( ext && !strcmp(ext, ".gz") ) 241 { 242 mdata->type = XPMPIPE; 243 mdata->stream.file = xpmPipeThrough(fd, "gunzip", "-qc", "r"); 244 } 245 else 246#endif /* z-files */ 247 { 248 mdata->type = XPMFILE; 249 mdata->stream.file = fdopen(fd, "r"); 250 } 251 if (!mdata->stream.file) 252 { 253 close(fd); 254 return (XpmOpenFailed); 255 } 256 } 257 mdata->CommentLength = 0; 258#ifdef CXPMPROG 259 mdata->lineNum = 0; 260 mdata->charNum = 0; 261#endif 262 return (XpmSuccess); 263} 264 265/* 266 * close the file related to the xpmData if any 267 */ 268static void 269xpmDataClose(xpmData *mdata) 270{ 271 if (mdata->stream.file != (stdin)) 272 fclose(mdata->stream.file); 273}