]> git.saurik.com Git - wxWidgets.git/blob - src/mac/xpm/WrFFrI.c
Themes crash fix.
[wxWidgets.git] / src / mac / xpm / WrFFrI.c
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 * WrFFrI.c: *
28 * *
29 * XPM library *
30 * Write an image and possibly its mask to an XPM file *
31 * *
32 * Developed by Arnaud Le Hors *
33 \*****************************************************************************/
34
35 /*
36 * The code related to AMIGA has been added by
37 * Lorens Younes (d93-hyo@nada.kth.se) 4/96
38 */
39
40 #include "xpmi.h"
41 #ifdef macintosh
42 #undef NO_ZPIPE
43 #define NO_ZPIPE
44 #endif
45 #if !defined(NO_ZPIPE) && defined(WIN32)
46 # define popen _popen
47 # define pclose _pclose
48 #endif
49
50 /* MS Windows define a function called WriteFile @#%#&!!! */
51 LFUNC(xpmWriteFile, int, (FILE *file, XpmImage *image, char *name,
52 XpmInfo *info));
53
54 LFUNC(WriteColors, void, (FILE *file, XpmColor *colors, unsigned int ncolors));
55
56 LFUNC(WritePixels, int, (FILE *file, unsigned int width, unsigned int height,
57 unsigned int cpp, unsigned int *pixels,
58 XpmColor *colors));
59
60 LFUNC(WriteExtensions, void, (FILE *file, XpmExtension *ext,
61 unsigned int num));
62
63 LFUNC(OpenWriteFile, int, (char *filename, xpmData *mdata));
64 LFUNC(xpmDataClose, void, (xpmData *mdata));
65
66 int
67 XpmWriteFileFromImage(display, filename, image, shapeimage, attributes)
68 Display *display;
69 char *filename;
70 XImage *image;
71 XImage *shapeimage;
72 XpmAttributes *attributes;
73 {
74 XpmImage xpmimage;
75 XpmInfo info;
76 int ErrorStatus;
77
78 /* create an XpmImage from the image */
79 ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage,
80 &xpmimage, attributes);
81 if (ErrorStatus != XpmSuccess)
82 return (ErrorStatus);
83
84 /* write the file from the XpmImage */
85 if (attributes) {
86 xpmSetInfo(&info, attributes);
87 ErrorStatus = XpmWriteFileFromXpmImage(filename, &xpmimage, &info);
88 } else
89 ErrorStatus = XpmWriteFileFromXpmImage(filename, &xpmimage, NULL);
90
91 /* free the XpmImage */
92 XpmFreeXpmImage(&xpmimage);
93
94 return (ErrorStatus);
95 }
96
97 int
98 XpmWriteFileFromXpmImage(filename, image, info)
99 char *filename;
100 XpmImage *image;
101 XpmInfo *info;
102 {
103 xpmData mdata;
104 char *name, *dot, *s, new_name[BUFSIZ];
105 int ErrorStatus;
106
107 /* open file to write */
108 if ((ErrorStatus = OpenWriteFile(filename, &mdata)) != XpmSuccess)
109 return (ErrorStatus);
110
111 /* figure out a name */
112 if (filename) {
113 #ifdef VMS
114 name = filename;
115 #else
116 if (!(name = rindex(filename, '/'))
117 #ifdef AMIGA
118 && !(name = rindex(filename, ':'))
119 #endif
120 )
121 name = filename;
122 else
123 name++;
124 #endif
125 /* let's try to make a valid C syntax name */
126 if (dot = index(name, '.')) {
127 strcpy(new_name, name);
128 /* change '.' to '_' */
129 name = s = new_name;
130 while (dot = index(s, '.')) {
131 *dot = '_';
132 s = dot;
133 }
134 }
135 if (dot = index(name, '-')) {
136 if (name != new_name) {
137 strcpy(new_name, name);
138 name = new_name;
139 }
140 /* change '-' to '_' */
141 s = name;
142 while (dot = index(s, '-')) {
143 *dot = '_';
144 s = dot;
145 }
146 }
147 } else
148 name = "image_name";
149
150 /* write the XpmData from the XpmImage */
151 if (ErrorStatus == XpmSuccess)
152 ErrorStatus = xpmWriteFile(mdata.stream.file, image, name, info);
153
154 xpmDataClose(&mdata);
155
156 return (ErrorStatus);
157 }
158
159 static int
160 xpmWriteFile(file, image, name, info)
161 FILE *file;
162 XpmImage *image;
163 char *name;
164 XpmInfo *info;
165 {
166 /* calculation variables */
167 unsigned int cmts, extensions;
168 int ErrorStatus;
169
170 cmts = info && (info->valuemask & XpmComments);
171 extensions = info && (info->valuemask & XpmExtensions)
172 && info->nextensions;
173
174 /* print the header line */
175 fprintf(file, "/* XPM */\nstatic char * %s[] = {\n", name);
176
177 /* print the hints line */
178 if (cmts && info->hints_cmt)
179 fprintf(file, "/*%s*/\n", info->hints_cmt);
180
181 fprintf(file, "\"%d %d %d %d", image->width, image->height,
182 image->ncolors, image->cpp);
183
184 if (info && (info->valuemask & XpmHotspot))
185 fprintf(file, " %d %d", info->x_hotspot, info->y_hotspot);
186
187 if (extensions)
188 fprintf(file, " XPMEXT");
189
190 fprintf(file, "\",\n");
191
192 /* print colors */
193 if (cmts && info->colors_cmt)
194 fprintf(file, "/*%s*/\n", info->colors_cmt);
195
196 WriteColors(file, image->colorTable, image->ncolors);
197
198 /* print pixels */
199 if (cmts && info->pixels_cmt)
200 fprintf(file, "/*%s*/\n", info->pixels_cmt);
201
202 ErrorStatus = WritePixels(file, image->width, image->height, image->cpp,
203 image->data, image->colorTable);
204 if (ErrorStatus != XpmSuccess)
205 return (ErrorStatus);
206
207 /* print extensions */
208 if (extensions)
209 WriteExtensions(file, info->extensions, info->nextensions);
210
211 /* close the array */
212 fprintf(file, "};\n");
213
214 return (XpmSuccess);
215 }
216
217 static void
218 WriteColors(file, colors, ncolors)
219 FILE *file;
220 XpmColor *colors;
221 unsigned int ncolors;
222 {
223 unsigned int a, key;
224 char *s;
225 char **defaults;
226
227 for (a = 0; a < ncolors; a++, colors++) {
228
229 defaults = (char **) colors;
230 fprintf(file, "\"%s", *defaults++);
231
232 for (key = 1; key <= NKEYS; key++, defaults++) {
233 if (s = *defaults)
234 fprintf(file, "\t%s %s", xpmColorKeys[key - 1], s);
235 }
236 fprintf(file, "\",\n");
237 }
238 }
239
240
241 static int
242 WritePixels(file, width, height, cpp, pixels, colors)
243 FILE *file;
244 unsigned int width;
245 unsigned int height;
246 unsigned int cpp;
247 unsigned int *pixels;
248 XpmColor *colors;
249 {
250 char *s, *p, *buf;
251 unsigned int x, y, h;
252
253 h = height - 1;
254 p = buf = (char *) XpmMalloc(width * cpp + 3);
255 if (!buf)
256 return (XpmNoMemory);
257 *buf = '"';
258 p++;
259 for (y = 0; y < h; y++) {
260 s = p;
261 for (x = 0; x < width; x++, pixels++) {
262 strncpy(s, colors[*pixels].string, cpp);
263 s += cpp;
264 }
265 *s++ = '"';
266 *s = '\0';
267 fprintf(file, "%s,\n", buf);
268 }
269 /* duplicate some code to avoid a test in the loop */
270 s = p;
271 for (x = 0; x < width; x++, pixels++) {
272 strncpy(s, colors[*pixels].string, cpp);
273 s += cpp;
274 }
275 *s++ = '"';
276 *s = '\0';
277 fprintf(file, "%s", buf);
278
279 XpmFree(buf);
280 return (XpmSuccess);
281 }
282
283 static void
284 WriteExtensions(file, ext, num)
285 FILE *file;
286 XpmExtension *ext;
287 unsigned int num;
288 {
289 unsigned int x, y, n;
290 char **line;
291
292 for (x = 0; x < num; x++, ext++) {
293 fprintf(file, ",\n\"XPMEXT %s\"", ext->name);
294 n = ext->nlines;
295 for (y = 0, line = ext->lines; y < n; y++, line++)
296 fprintf(file, ",\n\"%s\"", *line);
297 }
298 fprintf(file, ",\n\"XPMENDEXT\"");
299 }
300
301 /*
302 * open the given file to be written as an xpmData which is returned
303 */
304 static int
305 OpenWriteFile(filename, mdata)
306 char *filename;
307 xpmData *mdata;
308 {
309 #ifndef NO_ZPIPE
310 char buf[BUFSIZ];
311
312 #endif
313
314 if (!filename) {
315 mdata->stream.file = (stdout);
316 mdata->type = XPMFILE;
317 } else {
318 #ifndef NO_ZPIPE
319 int len = strlen(filename);
320 if (len > 2 && !strcmp(".Z", filename + (len - 2))) {
321 sprintf(buf, "compress > \"%s\"", filename);
322 if (!(mdata->stream.file = popen(buf, "w")))
323 return (XpmOpenFailed);
324
325 mdata->type = XPMPIPE;
326 } else if (len > 3 && !strcmp(".gz", filename + (len - 3))) {
327 sprintf(buf, "gzip -q > \"%s\"", filename);
328 if (!(mdata->stream.file = popen(buf, "w")))
329 return (XpmOpenFailed);
330
331 mdata->type = XPMPIPE;
332 } else {
333 #endif
334 if (!(mdata->stream.file = fopen(filename, "w")))
335 return (XpmOpenFailed);
336
337 mdata->type = XPMFILE;
338 #ifndef NO_ZPIPE
339 }
340 #endif
341 }
342 return (XpmSuccess);
343 }
344
345 /*
346 * close the file related to the xpmData if any
347 */
348 static void
349 xpmDataClose(mdata)
350 xpmData *mdata;
351 {
352 switch (mdata->type) {
353 case XPMFILE:
354 if (mdata->stream.file != (stdout))
355 fclose(mdata->stream.file);
356 break;
357 #ifndef NO_ZPIPE
358 case XPMPIPE:
359 pclose(mdata->stream.file);
360 break;
361 #endif
362 }
363 }