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
\*****************************************************************************/
37
* The code related to AMIGA has been added by
38
* Lorens Younes (d93-hyo@nada.kth.se) 4/96
48
#include "sys/types.h"
54
/* MS Windows define a function called WriteFile @#%#&!!! */
55
LFUNC(xpmWriteFile, int, (FILE *file, XpmImage *image, 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, (char *filename, xpmData *mdata));
68
LFUNC(xpmDataClose, void, (xpmData *mdata));
71
XpmWriteFileFromImage(display, filename, image, shapeimage, attributes)
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(filename, image, info)
108
char *name, *dot, *s, new_name[BUFSIZ] = {0};
111
/* open file to write */
112
if ((ErrorStatus = OpenWriteFile(filename, &mdata)) != XpmSuccess)
113
return (ErrorStatus);
115
/* figure out a name */
120
if (!(name = rindex(filename, '/'))
122
&& !(name = rindex(filename, ':'))
129
/* let's try to make a valid C syntax name */
130
if (index(name, '.')) {
131
strncpy(new_name, name, sizeof(new_name));
132
new_name[sizeof(new_name)-1] = '\0';
133
/* change '.' to '_' */
135
while ((dot = index(s, '.'))) {
140
if (index(name, '-')) {
141
if (name != new_name) {
142
strcpy(new_name, name);
145
/* change '-' to '_' */
147
while ((dot = index(s, '-'))) {
155
/* write the XpmData from the XpmImage */
156
if (ErrorStatus == XpmSuccess)
157
ErrorStatus = xpmWriteFile(mdata.stream.file, image, name, info);
159
xpmDataClose(&mdata);
161
return (ErrorStatus);
165
xpmWriteFile(file, image, name, info)
171
/* calculation variables */
172
unsigned int cmts, extensions;
175
cmts = info && (info->valuemask & XpmComments);
176
extensions = info && (info->valuemask & XpmExtensions)
177
&& info->nextensions;
179
/* print the header line */
180
fprintf(file, "/* XPM */\nstatic char * %s[] = {\n", name);
182
/* print the hints line */
183
if (cmts && info->hints_cmt)
184
fprintf(file, "/*%s*/\n", info->hints_cmt);
186
fprintf(file, "\"%d %d %d %d", image->width, image->height,
187
image->ncolors, image->cpp);
189
if (info && (info->valuemask & XpmHotspot))
190
fprintf(file, " %d %d", info->x_hotspot, info->y_hotspot);
193
fprintf(file, " XPMEXT");
195
fprintf(file, "\",\n");
198
if (cmts && info->colors_cmt)
199
fprintf(file, "/*%s*/\n", info->colors_cmt);
201
WriteColors(file, image->colorTable, image->ncolors);
204
if (cmts && info->pixels_cmt)
205
fprintf(file, "/*%s*/\n", info->pixels_cmt);
207
ErrorStatus = WritePixels(file, image->width, image->height, image->cpp,
208
image->data, image->colorTable);
209
if (ErrorStatus != XpmSuccess)
210
return (ErrorStatus);
212
/* print extensions */
214
WriteExtensions(file, info->extensions, info->nextensions);
216
/* close the array */
217
fprintf(file, "};\n");
223
WriteColors(file, colors, ncolors)
226
unsigned int ncolors;
232
for (a = 0; a < ncolors; a++, colors++) {
234
defaults = (char **) colors;
235
fprintf(file, "\"%s", *defaults++);
237
for (key = 1; key <= NKEYS; key++, defaults++) {
239
fprintf(file, "\t%s %s", xpmColorKeys[key - 1], s);
241
fprintf(file, "\",\n");
247
WritePixels(file, width, height, cpp, pixels, colors)
252
unsigned int *pixels;
256
unsigned int x, y, h;
259
if (cpp != 0 && width >= (UINT_MAX - 3)/cpp)
261
p = buf = (char *) XpmMalloc(width * cpp + 3);
263
return (XpmNoMemory);
266
for (y = 0; y < h; y++) {
268
for (x = 0; x < width; x++, pixels++) {
269
strncpy(s, colors[*pixels].string, cpp);
274
fprintf(file, "%s,\n", buf);
276
/* duplicate some code to avoid a test in the loop */
278
for (x = 0; x < width; x++, pixels++) {
279
strncpy(s, colors[*pixels].string, cpp);
284
fprintf(file, "%s", buf);
291
WriteExtensions(file, ext, num)
296
unsigned int x, y, n;
299
for (x = 0; x < num; x++, ext++) {
300
fprintf(file, ",\n\"XPMEXT %s\"", ext->name);
302
for (y = 0, line = ext->lines; y < n; y++, line++)
303
fprintf(file, ",\n\"%s\"", *line);
305
fprintf(file, ",\n\"XPMENDEXT\"");
310
FUNC(xpmPipeThrough, FILE*, (int fd,
317
* open the given file to be written as an xpmData which is returned
320
OpenWriteFile(filename, mdata)
325
mdata->stream.file = (stdout);
326
mdata->type = XPMFILE;
331
int fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644);
333
return(XpmOpenFailed);
335
len = strlen(filename);
336
if (len > 2 && !strcmp(".Z", filename + (len - 2))) {
337
mdata->stream.file = xpmPipeThrough(fd, "compress", NULL, "w");
338
mdata->type = XPMPIPE;
339
} else if (len > 3 && !strcmp(".gz", filename + (len - 3))) {
340
mdata->stream.file = xpmPipeThrough(fd, "gzip", "-q", "w");
341
mdata->type = XPMPIPE;
345
mdata->stream.file = fdopen(fd, "w");
346
mdata->type = XPMFILE;
348
if (!mdata->stream.file)
349
return (XpmOpenFailed);
355
* close the file related to the xpmData if any
361
if (mdata->stream.file != (stdout))
362
fclose(mdata->stream.file);