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