~ubuntu-branches/ubuntu/lucid/libxpm/lucid

« back to all changes in this revision

Viewing changes to src/WrFFrI.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Stone
  • Date: 2005-07-23 01:33:31 UTC
  • Revision ID: james.westby@ubuntu.com-20050723013331-3azqgwnbdc7sjosd
Tags: upstream-3.5.2
ImportĀ upstreamĀ versionĀ 3.5.2

Show diffs side-by-side

added added

removed removed

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