2 * Copyright (C) 1989-95 GROUPE BULL
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
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.
26 /*****************************************************************************\
30 * Write an image and possibly its mask to an XPM file *
32 * Developed by Arnaud Le Hors *
33 \*****************************************************************************/
36 * The code related to AMIGA has been added by
37 * Lorens Younes (d93-hyo@nada.kth.se) 4/96
47 #include "sys/types.h"
54 /* MS Windows define a function called WriteFile @#%#&!!! */
55 LFUNC(xpmWriteFile, int, (FILE *file, XpmImage *image, const char *name,
58 LFUNC(WriteColors, void, (FILE *file, XpmColor *colors, unsigned int ncolors));
60 LFUNC(WritePixels, int, (FILE *file, unsigned int width, unsigned int height,
61 unsigned int cpp, unsigned int *pixels,
64 LFUNC(WriteExtensions, void, (FILE *file, XpmExtension *ext,
67 LFUNC(OpenWriteFile, int, (const char *filename, xpmData *mdata));
68 LFUNC(xpmDataClose, void, (xpmData *mdata));
71 XpmWriteFileFromImage(
76 XpmAttributes *attributes)
82 /* create an XpmImage from the image */
83 ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage,
84 &xpmimage, attributes);
85 if (ErrorStatus != XpmSuccess)
88 /* write the file from the XpmImage */
90 xpmSetInfo(&info, attributes);
91 ErrorStatus = XpmWriteFileFromXpmImage(filename, &xpmimage, &info);
93 ErrorStatus = XpmWriteFileFromXpmImage(filename, &xpmimage, NULL);
95 /* free the XpmImage */
96 XpmFreeXpmImage(&xpmimage);
102 XpmWriteFileFromXpmImage(
103 const char *filename,
109 char *dot, *s, new_name[BUFSIZ] = {0};
112 /* open file to write */
113 if ((ErrorStatus = OpenWriteFile(filename, &mdata)) != XpmSuccess)
114 return (ErrorStatus);
116 /* figure out a name */
121 if (!(name = strrchr(filename, '/'))
123 && !(name = strrchr(filename, ':'))
130 /* let's try to make a valid C syntax name */
131 if (strchr(name, '.')) {
132 strncpy(new_name, name, sizeof(new_name));
133 new_name[sizeof(new_name)-1] = '\0';
134 /* change '.' to '_' */
136 while ((dot = strchr(s, '.'))) {
141 if (strchr(name, '-')) {
142 if (name != new_name) {
143 strncpy(new_name, name, sizeof(new_name));
144 new_name[sizeof(new_name)-1] = '\0';
147 /* change '-' to '_' */
149 while ((dot = strchr(s, '-'))) {
157 /* write the XpmData from the XpmImage */
158 if (ErrorStatus == XpmSuccess)
159 ErrorStatus = xpmWriteFile(mdata.stream.file, image, name, info);
161 xpmDataClose(&mdata);
163 return (ErrorStatus);
173 /* calculation variables */
174 unsigned int cmts, extensions;
177 cmts = info && (info->valuemask & XpmComments);
178 extensions = info && (info->valuemask & XpmExtensions)
179 && info->nextensions;
181 /* print the header line */
182 fprintf(file, "/* XPM */\nstatic char * %s[] = {\n", name);
184 /* print the hints line */
185 if (cmts && info->hints_cmt)
186 fprintf(file, "/*%s*/\n", info->hints_cmt);
188 fprintf(file, "\"%d %d %d %d", image->width, image->height,
189 image->ncolors, image->cpp);
191 if (info && (info->valuemask & XpmHotspot))
192 fprintf(file, " %d %d", info->x_hotspot, info->y_hotspot);
195 fprintf(file, " XPMEXT");
197 fprintf(file, "\",\n");
200 if (cmts && info->colors_cmt)
201 fprintf(file, "/*%s*/\n", info->colors_cmt);
203 WriteColors(file, image->colorTable, image->ncolors);
206 if (cmts && info->pixels_cmt)
207 fprintf(file, "/*%s*/\n", info->pixels_cmt);
209 ErrorStatus = WritePixels(file, image->width, image->height, image->cpp,
210 image->data, image->colorTable);
211 if (ErrorStatus != XpmSuccess)
212 return (ErrorStatus);
214 /* print extensions */
216 WriteExtensions(file, info->extensions, info->nextensions);
218 /* close the array */
219 fprintf(file, "};\n");
228 unsigned int ncolors)
234 for (a = 0; a < ncolors; a++, colors++) {
236 defaults = (char **) colors;
237 fprintf(file, "\"%s", *defaults++);
239 for (key = 1; key <= NKEYS; key++, defaults++) {
241 fprintf(file, "\t%s %s", xpmColorKeys[key - 1], s);
243 fprintf(file, "\",\n");
254 unsigned int *pixels,
258 unsigned int x, y, h;
261 if (cpp != 0 && width >= (UINT_MAX - 3)/cpp)
263 p = buf = (char *) XpmMalloc(width * cpp + 3);
265 return (XpmNoMemory);
268 for (y = 0; y < h; y++) {
270 for (x = 0; x < width; x++, pixels++) {
271 strncpy(s, colors[*pixels].string, cpp);
276 fprintf(file, "%s,\n", buf);
278 /* duplicate some code to avoid a test in the loop */
280 for (x = 0; x < width; x++, pixels++) {
281 strncpy(s, colors[*pixels].string, cpp);
286 fprintf(file, "%s", buf);
298 unsigned int x, y, n;
301 for (x = 0; x < num; x++, ext++) {
302 fprintf(file, ",\n\"XPMEXT %s\"", ext->name);
304 for (y = 0, line = ext->lines; y < n; y++, line++)
305 fprintf(file, ",\n\"%s\"", *line);
307 fprintf(file, ",\n\"XPMENDEXT\"");
312 FUNC(xpmPipeThrough, FILE*, (int fd,
319 * open the given file to be written as an xpmData which is returned
323 const char *filename,
327 mdata->stream.file = (stdout);
328 mdata->type = XPMFILE;
333 int fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644);
335 return(XpmOpenFailed);
337 len = strlen(filename);
338 if (len > 2 && !strcmp(".Z", filename + (len - 2))) {
339 mdata->stream.file = xpmPipeThrough(fd, "compress", NULL, "w");
340 mdata->type = XPMPIPE;
341 } else if (len > 3 && !strcmp(".gz", filename + (len - 3))) {
342 mdata->stream.file = xpmPipeThrough(fd, "gzip", "-q", "w");
343 mdata->type = XPMPIPE;
347 mdata->stream.file = fdopen(fd, "w");
348 mdata->type = XPMFILE;
350 if (!mdata->stream.file) {
352 return (XpmOpenFailed);
359 * close the file related to the xpmData if any
362 xpmDataClose(xpmData *mdata)
364 if (mdata->stream.file != (stdout))
365 fclose(mdata->stream.file);