]> git.saurik.com Git - wxWidgets.git/blame - src/xpm/WrFFrI.c
blind fix for wxGIFDecoder::ReadGIF
[wxWidgets.git] / src / xpm / WrFFrI.c
CommitLineData
cfbe03c9 1/*
e6ed776f 2 * Copyright (C) 1989-95 GROUPE BULL
cfbe03c9
JS
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/*****************************************************************************\
e6ed776f 27* WrFFrI.c: *
cfbe03c9
JS
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
e6ed776f
GRG
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#if !defined(NO_ZPIPE) && defined(WIN32)
42# define popen _popen
43# define pclose _pclose
cfbe03c9
JS
44#endif
45
e6ed776f
GRG
46/* MS Windows define a function called WriteFile @#%#&!!! */
47LFUNC(xpmWriteFile, int, (FILE *file, XpmImage *image, char *name,
48 XpmInfo *info));
cfbe03c9
JS
49
50LFUNC(WriteColors, void, (FILE *file, XpmColor *colors, unsigned int ncolors));
51
52LFUNC(WritePixels, int, (FILE *file, unsigned int width, unsigned int height,
53 unsigned int cpp, unsigned int *pixels,
54 XpmColor *colors));
55
56LFUNC(WriteExtensions, void, (FILE *file, XpmExtension *ext,
57 unsigned int num));
58
e6ed776f
GRG
59LFUNC(OpenWriteFile, int, (char *filename, xpmData *mdata));
60LFUNC(xpmDataClose, void, (xpmData *mdata));
61
ea258ad3
DW
62#ifdef __OS2__
63/* Visual Age cannot deal with old, non-ansi, code */
64int XpmWriteFileFromImage(
65 Display* display
66, char* filename
67, XImage* image
68, XImage* shapeimage
69, XpmAttributes* attributes
70)
71#else
cfbe03c9 72int
e6ed776f
GRG
73XpmWriteFileFromImage(display, filename, image, shapeimage, attributes)
74 Display *display;
75 char *filename;
76 XImage *image;
77 XImage *shapeimage;
78 XpmAttributes *attributes;
ea258ad3 79#endif
cfbe03c9
JS
80{
81 XpmImage xpmimage;
82 XpmInfo info;
83 int ErrorStatus;
84
85 /* create an XpmImage from the image */
86 ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage,
87 &xpmimage, attributes);
88 if (ErrorStatus != XpmSuccess)
89 return (ErrorStatus);
90
91 /* write the file from the XpmImage */
92 if (attributes) {
93 xpmSetInfo(&info, attributes);
94 ErrorStatus = XpmWriteFileFromXpmImage(filename, &xpmimage, &info);
95 } else
96 ErrorStatus = XpmWriteFileFromXpmImage(filename, &xpmimage, NULL);
97
98 /* free the XpmImage */
99 XpmFreeXpmImage(&xpmimage);
100
101 return (ErrorStatus);
102}
103
ea258ad3
DW
104#ifdef __OS2__
105/* Visual Age cannot deal with old, non-ansi, code */
106int XpmWriteFileFromXpmImage(
107 char* filename
108, XpmImage* image
109, XpmInfo* info
110)
111#else
cfbe03c9 112int
e6ed776f
GRG
113XpmWriteFileFromXpmImage(filename, image, info)
114 char *filename;
115 XpmImage *image;
116 XpmInfo *info;
ea258ad3 117#endif
cfbe03c9
JS
118{
119 xpmData mdata;
120 char *name, *dot, *s, new_name[BUFSIZ];
121 int ErrorStatus;
cfbe03c9
JS
122
123 /* open file to write */
e6ed776f 124 if ((ErrorStatus = OpenWriteFile(filename, &mdata)) != XpmSuccess)
cfbe03c9
JS
125 return (ErrorStatus);
126
127 /* figure out a name */
128 if (filename) {
129#ifdef VMS
130 name = filename;
131#else
e6ed776f
GRG
132 if (!(name = rindex(filename, '/'))
133#ifdef AMIGA
134 && !(name = rindex(filename, ':'))
cfbe03c9 135#endif
e6ed776f 136 )
cfbe03c9
JS
137 name = filename;
138 else
139 name++;
140#endif
e6ed776f
GRG
141 /* let's try to make a valid C syntax name */
142 if (dot = index(name, '.')) {
cfbe03c9 143 strcpy(new_name, name);
e6ed776f 144 /* change '.' to '_' */
cfbe03c9 145 name = s = new_name;
e6ed776f
GRG
146 while (dot = index(s, '.')) {
147 *dot = '_';
148 s = dot;
149 }
150 }
151 if (dot = index(name, '-')) {
152 if (name != new_name) {
153 strcpy(new_name, name);
154 name = new_name;
155 }
156 /* change '-' to '_' */
157 s = name;
158 while (dot = index(s, '-')) {
cfbe03c9
JS
159 *dot = '_';
160 s = dot;
161 }
162 }
163 } else
164 name = "image_name";
165
166 /* write the XpmData from the XpmImage */
167 if (ErrorStatus == XpmSuccess)
e6ed776f 168 ErrorStatus = xpmWriteFile(mdata.stream.file, image, name, info);
cfbe03c9
JS
169
170 xpmDataClose(&mdata);
171
172 return (ErrorStatus);
173}
174
ea258ad3
DW
175#ifdef __OS2__
176/* Visual Age cannot deal with old, non-ansi, code */
177static int
178xpmWriteFile(
179 FILE* file
180, XpmImage* image
181, char* name
182, XpmInfo* info
183)
184#else
e6ed776f
GRG
185static int
186xpmWriteFile(file, image, name, info)
187 FILE *file;
188 XpmImage *image;
189 char *name;
190 XpmInfo *info;
ea258ad3 191#endif
cfbe03c9
JS
192{
193 /* calculation variables */
194 unsigned int cmts, extensions;
cfbe03c9
JS
195 int ErrorStatus;
196
cfbe03c9
JS
197 cmts = info && (info->valuemask & XpmComments);
198 extensions = info && (info->valuemask & XpmExtensions)
199 && info->nextensions;
200
201 /* print the header line */
202 fprintf(file, "/* XPM */\nstatic char * %s[] = {\n", name);
203
204 /* print the hints line */
205 if (cmts && info->hints_cmt)
206 fprintf(file, "/*%s*/\n", info->hints_cmt);
207
208 fprintf(file, "\"%d %d %d %d", image->width, image->height,
209 image->ncolors, image->cpp);
210
211 if (info && (info->valuemask & XpmHotspot))
212 fprintf(file, " %d %d", info->x_hotspot, info->y_hotspot);
213
214 if (extensions)
215 fprintf(file, " XPMEXT");
216
217 fprintf(file, "\",\n");
218
219 /* print colors */
220 if (cmts && info->colors_cmt)
221 fprintf(file, "/*%s*/\n", info->colors_cmt);
222
223 WriteColors(file, image->colorTable, image->ncolors);
224
225 /* print pixels */
226 if (cmts && info->pixels_cmt)
227 fprintf(file, "/*%s*/\n", info->pixels_cmt);
228
229 ErrorStatus = WritePixels(file, image->width, image->height, image->cpp,
230 image->data, image->colorTable);
231 if (ErrorStatus != XpmSuccess)
232 return (ErrorStatus);
233
234 /* print extensions */
235 if (extensions)
236 WriteExtensions(file, info->extensions, info->nextensions);
237
238 /* close the array */
239 fprintf(file, "};\n");
240
241 return (XpmSuccess);
242}
243
ea258ad3
DW
244#ifdef __OS2__
245/* Visual Age cannot deal with old, non-ansi, code */
246static void
247WriteColors(
248 FILE* file
249, XpmColor* colors
250, unsigned int ncolors
251)
252#else
cfbe03c9 253static void
e6ed776f
GRG
254WriteColors(file, colors, ncolors)
255 FILE *file;
256 XpmColor *colors;
257 unsigned int ncolors;
ea258ad3 258#endif
cfbe03c9
JS
259{
260 unsigned int a, key;
261 char *s;
262 char **defaults;
263
264 for (a = 0; a < ncolors; a++, colors++) {
265
266 defaults = (char **) colors;
267 fprintf(file, "\"%s", *defaults++);
268
269 for (key = 1; key <= NKEYS; key++, defaults++) {
270 if (s = *defaults)
271 fprintf(file, "\t%s %s", xpmColorKeys[key - 1], s);
272 }
273 fprintf(file, "\",\n");
274 }
275}
276
ea258ad3
DW
277#ifdef __OS2__
278/* Visual Age cannot deal with old, non-ansi, code */
279static int WritePixels(
280 FILE* file
281, unsigned int width
282, unsigned int height
283, unsigned int cpp
284, unsigned int* pixels
285, XpmColor* colors
286)
287#else
cfbe03c9 288static int
e6ed776f
GRG
289WritePixels(file, width, height, cpp, pixels, colors)
290 FILE *file;
291 unsigned int width;
292 unsigned int height;
293 unsigned int cpp;
294 unsigned int *pixels;
295 XpmColor *colors;
ea258ad3 296#endif
cfbe03c9
JS
297{
298 char *s, *p, *buf;
299 unsigned int x, y, h;
300
301 h = height - 1;
302 p = buf = (char *) XpmMalloc(width * cpp + 3);
303 if (!buf)
304 return (XpmNoMemory);
305 *buf = '"';
306 p++;
307 for (y = 0; y < h; y++) {
308 s = p;
309 for (x = 0; x < width; x++, pixels++) {
310 strncpy(s, colors[*pixels].string, cpp);
311 s += cpp;
312 }
313 *s++ = '"';
314 *s = '\0';
315 fprintf(file, "%s,\n", buf);
316 }
317 /* duplicate some code to avoid a test in the loop */
318 s = p;
319 for (x = 0; x < width; x++, pixels++) {
320 strncpy(s, colors[*pixels].string, cpp);
321 s += cpp;
322 }
323 *s++ = '"';
324 *s = '\0';
325 fprintf(file, "%s", buf);
326
327 XpmFree(buf);
328 return (XpmSuccess);
329}
330
ea258ad3
DW
331#ifdef __OS2__
332/* Visual Age cannot deal with old, non-ansi, code */
333static void WriteExtensions(
334 FILE* file
335, XpmExtension* ext
336, unsigned int num
337)
338#else
cfbe03c9 339static void
e6ed776f
GRG
340WriteExtensions(file, ext, num)
341 FILE *file;
342 XpmExtension *ext;
343 unsigned int num;
ea258ad3 344#endif
cfbe03c9
JS
345{
346 unsigned int x, y, n;
347 char **line;
348
349 for (x = 0; x < num; x++, ext++) {
350 fprintf(file, ",\n\"XPMEXT %s\"", ext->name);
351 n = ext->nlines;
352 for (y = 0, line = ext->lines; y < n; y++, line++)
353 fprintf(file, ",\n\"%s\"", *line);
354 }
355 fprintf(file, ",\n\"XPMENDEXT\"");
356}
e6ed776f
GRG
357
358/*
359 * open the given file to be written as an xpmData which is returned
360 */
ea258ad3
DW
361#ifdef __OS2__
362#define popen fopen
363#define pclose fclose
364/* Visual Age cannot deal with old, non-ansi, code */
365static int OpenWriteFile(
366 char* filename
367, xpmData* mdata
368)
369#else
e6ed776f
GRG
370static int
371OpenWriteFile(filename, mdata)
372 char *filename;
373 xpmData *mdata;
ea258ad3 374#endif
e6ed776f
GRG
375{
376#ifndef NO_ZPIPE
377 char buf[BUFSIZ];
378
379#endif
380
381 if (!filename) {
382 mdata->stream.file = (stdout);
383 mdata->type = XPMFILE;
384 } else {
385#ifndef NO_ZPIPE
386 int len = strlen(filename);
387 if (len > 2 && !strcmp(".Z", filename + (len - 2))) {
388 sprintf(buf, "compress > \"%s\"", filename);
389 if (!(mdata->stream.file = popen(buf, "w")))
390 return (XpmOpenFailed);
391
392 mdata->type = XPMPIPE;
393 } else if (len > 3 && !strcmp(".gz", filename + (len - 3))) {
394 sprintf(buf, "gzip -q > \"%s\"", filename);
395 if (!(mdata->stream.file = popen(buf, "w")))
396 return (XpmOpenFailed);
397
398 mdata->type = XPMPIPE;
399 } else {
400#endif
401 if (!(mdata->stream.file = fopen(filename, "w")))
402 return (XpmOpenFailed);
403
404 mdata->type = XPMFILE;
405#ifndef NO_ZPIPE
406 }
407#endif
408 }
409 return (XpmSuccess);
410}
411
412/*
413 * close the file related to the xpmData if any
414 */
ea258ad3
DW
415#ifdef __OS2__
416/* Visual Age cannot deal with old, non-ansi, code */
417static void xpmDataClose(xpmData* mdata)
418#else
e6ed776f
GRG
419static void
420xpmDataClose(mdata)
421 xpmData *mdata;
ea258ad3 422#endif
e6ed776f
GRG
423{
424 switch (mdata->type) {
425 case XPMFILE:
426 if (mdata->stream.file != (stdout))
427 fclose(mdata->stream.file);
428 break;
429#ifndef NO_ZPIPE
430 case XPMPIPE:
431 pclose(mdata->stream.file);
432 break;
433#endif
434 }
435}