]> git.saurik.com Git - wxWidgets.git/blame - src/xpm/CrBufFrI.c
XPM updates
[wxWidgets.git] / src / xpm / CrBufFrI.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* CrBufFrI.c: *
cfbe03c9
JS
28* *
29* XPM library *
30* Scan an image and possibly its mask and create an XPM buffer *
31* *
32* Developed by Arnaud Le Hors *
33\*****************************************************************************/
34
e6ed776f 35#include "XpmI.h"
cfbe03c9
JS
36
37LFUNC(WriteColors, int, (char **dataptr, unsigned int *data_size,
38 unsigned int *used_size, XpmColor *colors,
39 unsigned int ncolors, unsigned int cpp));
40
41LFUNC(WritePixels, void, (char *dataptr, unsigned int *used_size,
42 unsigned int width, unsigned int height,
43 unsigned int cpp, unsigned int *pixels,
44 XpmColor *colors));
45
46LFUNC(WriteExtensions, void, (char *dataptr, unsigned int *used_size,
47 XpmExtension *ext, unsigned int num));
48
49LFUNC(ExtensionsSize, int, (XpmExtension *ext, unsigned int num));
50LFUNC(CommentsSize, int, (XpmInfo *info));
51
ea258ad3
DW
52#ifdef __OS2__
53/* Visual Age cannot deal with old, non-ansi, code */
54int XpmCreateBufferFromImage(
55 Display* display
56, char** buffer_return
57, XImage* image
58, XImage* shapeimage
59, XpmAttributes* attributes
60)
61#else
cfbe03c9 62int
e6ed776f
GRG
63XpmCreateBufferFromImage(display, buffer_return, image, shapeimage, attributes)
64 Display *display;
65 char **buffer_return;
66 XImage *image;
67 XImage *shapeimage;
68 XpmAttributes *attributes;
ea258ad3 69#endif
cfbe03c9
JS
70{
71 XpmImage xpmimage;
72 XpmInfo info;
73 int ErrorStatus;
74
75 /* initialize return value */
76 if (buffer_return)
77 *buffer_return = NULL;
78
79 /* create an XpmImage from the image */
80 ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage,
81 &xpmimage, attributes);
82 if (ErrorStatus != XpmSuccess)
83 return (ErrorStatus);
84
85 /* create the buffer from the XpmImage */
86 if (attributes) {
87 xpmSetInfo(&info, attributes);
88 ErrorStatus =
89 XpmCreateBufferFromXpmImage(buffer_return, &xpmimage, &info);
90 } else
91 ErrorStatus =
92 XpmCreateBufferFromXpmImage(buffer_return, &xpmimage, NULL);
93
94 /* free the XpmImage */
95 XpmFreeXpmImage(&xpmimage);
96
97 return (ErrorStatus);
98}
99
100
101#undef RETURN
102#define RETURN(status) \
103{ \
e6ed776f
GRG
104 ErrorStatus = status; \
105 goto error; \
cfbe03c9
JS
106}
107
ea258ad3
DW
108#ifdef __OS2__
109/* Visual Age cannot deal with old, non-ansi, code */
110int XpmCreateBufferFromXpmImage(char** buffer_return, XpmImage* image, XpmInfo* info)
111#else
cfbe03c9 112int
e6ed776f
GRG
113XpmCreateBufferFromXpmImage(buffer_return, image, info)
114 char **buffer_return;
115 XpmImage *image;
116 XpmInfo *info;
ea258ad3 117#endif
cfbe03c9
JS
118{
119 /* calculation variables */
120 int ErrorStatus;
121 char buf[BUFSIZ];
122 unsigned int cmts, extensions, ext_size = 0;
123 unsigned int l, cmt_size = 0;
124 char *ptr = NULL, *p;
125 unsigned int ptr_size, used_size;
126
127 *buffer_return = NULL;
128
129 cmts = info && (info->valuemask & XpmComments);
130 extensions = info && (info->valuemask & XpmExtensions)
131 && info->nextensions;
132
133 /* compute the extensions and comments size */
134 if (extensions)
135 ext_size = ExtensionsSize(info->extensions, info->nextensions);
136 if (cmts)
137 cmt_size = CommentsSize(info);
138
139 /* write the header line */
e6ed776f
GRG
140#ifndef VOID_SPRINTF
141 used_size =
142#endif
cfbe03c9 143 sprintf(buf, "/* XPM */\nstatic char * image_name[] = {\n");
e6ed776f 144#ifdef VOID_SPRINTF
cfbe03c9 145 used_size = strlen(buf);
e6ed776f 146#endif
cfbe03c9
JS
147 ptr_size = used_size + ext_size + cmt_size + 1;
148 ptr = (char *) XpmMalloc(ptr_size);
149 if (!ptr)
150 return XpmNoMemory;
151 strcpy(ptr, buf);
152
153 /* write the values line */
154 if (cmts && info->hints_cmt) {
e6ed776f
GRG
155#ifndef VOID_SPRINTF
156 used_size +=
157#endif
cfbe03c9 158 sprintf(ptr + used_size, "/*%s*/\n", info->hints_cmt);
e6ed776f 159#ifdef VOID_SPRINTF
cfbe03c9 160 used_size += strlen(info->hints_cmt) + 5;
e6ed776f 161#endif
cfbe03c9 162 }
e6ed776f
GRG
163#ifndef VOID_SPRINTF
164 l =
165#endif
cfbe03c9
JS
166 sprintf(buf, "\"%d %d %d %d", image->width, image->height,
167 image->ncolors, image->cpp);
e6ed776f 168#ifdef VOID_SPRINTF
cfbe03c9 169 l = strlen(buf);
e6ed776f 170#endif
cfbe03c9
JS
171
172 if (info && (info->valuemask & XpmHotspot)) {
e6ed776f
GRG
173#ifndef VOID_SPRINTF
174 l +=
175#endif
cfbe03c9 176 sprintf(buf + l, " %d %d", info->x_hotspot, info->y_hotspot);
e6ed776f 177#ifdef VOID_SPRINTF
cfbe03c9 178 l = strlen(buf);
e6ed776f 179#endif
cfbe03c9
JS
180 }
181 if (extensions) {
e6ed776f
GRG
182#ifndef VOID_SPRINTF
183 l +=
184#endif
cfbe03c9 185 sprintf(buf + l, " XPMEXT");
e6ed776f 186#ifdef VOID_SPRINTF
cfbe03c9 187 l = strlen(buf);
e6ed776f 188#endif
cfbe03c9 189 }
e6ed776f
GRG
190#ifndef VOID_SPRINTF
191 l +=
192#endif
cfbe03c9 193 sprintf(buf + l, "\",\n");
e6ed776f 194#ifdef VOID_SPRINTF
cfbe03c9 195 l = strlen(buf);
e6ed776f 196#endif
cfbe03c9
JS
197 ptr_size += l;
198 p = (char *) XpmRealloc(ptr, ptr_size);
199 if (!p)
200 RETURN(XpmNoMemory);
201 ptr = p;
202 strcpy(ptr + used_size, buf);
203 used_size += l;
204
205 /* write colors */
206 if (cmts && info->colors_cmt) {
e6ed776f
GRG
207#ifndef VOID_SPRINTF
208 used_size +=
209#endif
cfbe03c9 210 sprintf(ptr + used_size, "/*%s*/\n", info->colors_cmt);
e6ed776f 211#ifdef VOID_SPRINTF
cfbe03c9 212 used_size += strlen(info->colors_cmt) + 5;
e6ed776f 213#endif
cfbe03c9
JS
214 }
215 ErrorStatus = WriteColors(&ptr, &ptr_size, &used_size,
216 image->colorTable, image->ncolors, image->cpp);
ea258ad3 217
cfbe03c9
JS
218 if (ErrorStatus != XpmSuccess)
219 RETURN(ErrorStatus);
220
221 /*
e6ed776f
GRG
222 * now we know the exact size we need, realloc the data
223 * 4 = 1 (for '"') + 3 (for '",\n')
224 * 1 = - 2 (because the last line does not end with ',\n') + 3 (for '};\n')
cfbe03c9
JS
225 */
226 ptr_size += image->height * (image->width * image->cpp + 4) + 1;
227
228 p = (char *) XpmRealloc(ptr, ptr_size);
229 if (!p)
230 RETURN(XpmNoMemory);
231 ptr = p;
232
233 /* print pixels */
234 if (cmts && info->pixels_cmt) {
e6ed776f
GRG
235#ifndef VOID_SPRINTF
236 used_size +=
237#endif
cfbe03c9 238 sprintf(ptr + used_size, "/*%s*/\n", info->pixels_cmt);
e6ed776f 239#ifdef VOID_SPRINTF
cfbe03c9 240 used_size += strlen(info->pixels_cmt) + 5;
e6ed776f 241#endif
cfbe03c9
JS
242 }
243 WritePixels(ptr + used_size, &used_size, image->width, image->height,
244 image->cpp, image->data, image->colorTable);
245
246 /* print extensions */
247 if (extensions)
248 WriteExtensions(ptr + used_size, &used_size,
249 info->extensions, info->nextensions);
250
251 /* close the array */
e6ed776f 252 strcpy(ptr + used_size, "};\n");
cfbe03c9
JS
253
254 *buffer_return = ptr;
255
256 return (XpmSuccess);
e6ed776f
GRG
257
258/* exit point in case of error, free only locally allocated variables */
259error:
260 if (ptr)
261 XpmFree(ptr);
262 return (ErrorStatus);
cfbe03c9
JS
263}
264
ea258ad3
DW
265#ifdef __OS2__
266/* Visual Age cannot deal with old, non-ansi, code */
267static int WriteColors(
268 char** dataptr
269, unsigned int* data_size
270, unsigned int* used_size
271, XpmColor* colors
272, unsigned int ncolors
273, unsigned int cpp
274)
275#else
cfbe03c9 276static int
e6ed776f
GRG
277WriteColors(dataptr, data_size, used_size, colors, ncolors, cpp)
278 char **dataptr;
279 unsigned int *data_size;
280 unsigned int *used_size;
281 XpmColor *colors;
282 unsigned int ncolors;
283 unsigned int cpp;
ea258ad3 284#endif
cfbe03c9
JS
285{
286 char buf[BUFSIZ];
287 unsigned int a, key, l;
288 char *s, *s2;
289 char **defaults;
290
291 *buf = '"';
292 for (a = 0; a < ncolors; a++, colors++) {
293
294 defaults = (char **) colors;
295 s = buf + 1;
296 strncpy(s, *defaults++, cpp);
297 s += cpp;
298
299 for (key = 1; key <= NKEYS; key++, defaults++) {
300 if (s2 = *defaults) {
e6ed776f
GRG
301#ifndef VOID_SPRINTF
302 s +=
303#endif
cfbe03c9 304 sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2);
e6ed776f 305#ifdef VOID_SPRINTF
cfbe03c9 306 s += strlen(s);
e6ed776f 307#endif
cfbe03c9
JS
308 }
309 }
310 strcpy(s, "\",\n");
e6ed776f 311 l = s + 3 - buf;
cfbe03c9
JS
312 s = (char *) XpmRealloc(*dataptr, *data_size + l);
313 if (!s)
314 return (XpmNoMemory);
315 *data_size += l;
316 strcpy(s + *used_size, buf);
317 *used_size += l;
318 *dataptr = s;
319 }
320 return (XpmSuccess);
321}
322
ea258ad3
DW
323#ifdef __OS2__
324/* Visual Age cannot deal with old, non-ansi, code */
325static void WritePixels(
326 char* dataptr
327, unsigned int* used_size
328, unsigned int width
329, unsigned int height
330, unsigned int cpp
331, unsigned int* pixels
332, XpmColor* colors
333)
334#else
cfbe03c9 335static void
e6ed776f
GRG
336WritePixels(dataptr, used_size, width, height, cpp, pixels, colors)
337 char *dataptr;
338 unsigned int *used_size;
339 unsigned int width;
340 unsigned int height;
341 unsigned int cpp;
342 unsigned int *pixels;
343 XpmColor *colors;
ea258ad3 344#endif
cfbe03c9
JS
345{
346 char *s = dataptr;
347 unsigned int x, y, h;
348
349 h = height - 1;
350 for (y = 0; y < h; y++) {
351 *s++ = '"';
352 for (x = 0; x < width; x++, pixels++) {
353 strncpy(s, colors[*pixels].string, cpp);
354 s += cpp;
355 }
356 strcpy(s, "\",\n");
357 s += 3;
358 }
359 /* duplicate some code to avoid a test in the loop */
360 *s++ = '"';
361 for (x = 0; x < width; x++, pixels++) {
362 strncpy(s, colors[*pixels].string, cpp);
363 s += cpp;
364 }
365 *s++ = '"';
366 *used_size += s - dataptr;
367}
368
ea258ad3
DW
369#ifdef __OS2__
370/* Visual Age cannot deal with old, non-ansi, code */
371static int
372ExtensionsSize(XpmExtension* ext, unsigned int num)
373#else
cfbe03c9 374static int
e6ed776f
GRG
375ExtensionsSize(ext, num)
376 XpmExtension *ext;
377 unsigned int num;
ea258ad3 378#endif
cfbe03c9
JS
379{
380 unsigned int x, y, a, size;
381 char **line;
382
383 size = 0;
384 for (x = 0; x < num; x++, ext++) {
385 /* 11 = 10 (for ',\n"XPMEXT ') + 1 (for '"') */
386 size += strlen(ext->name) + 11;
387 a = ext->nlines;
388 for (y = 0, line = ext->lines; y < a; y++, line++)
389 /* 4 = 3 (for ',\n"') + 1 (for '"') */
390 size += strlen(*line) + 4;
391 }
392 /* 13 is for ',\n"XPMENDEXT"' */
393 return size + 13;
394}
395
ea258ad3
DW
396#ifdef __OS2__
397/* Visual Age cannot deal with old, non-ansi, code */
398static void WriteExtensions(
399 char* dataptr
400, unsigned int* used_size
401, XpmExtension* ext
402, unsigned int num
403)
404#else
cfbe03c9 405static void
e6ed776f
GRG
406WriteExtensions(dataptr, used_size, ext, num)
407 char *dataptr;
408 unsigned int *used_size;
409 XpmExtension *ext;
410 unsigned int num;
ea258ad3 411#endif
cfbe03c9
JS
412{
413 unsigned int x, y, a;
414 char **line;
415 char *s = dataptr;
416
417 for (x = 0; x < num; x++, ext++) {
e6ed776f
GRG
418#ifndef VOID_SPRINTF
419 s +=
420#endif
cfbe03c9 421 sprintf(s, ",\n\"XPMEXT %s\"", ext->name);
e6ed776f 422#ifdef VOID_SPRINTF
cfbe03c9 423 s += strlen(ext->name) + 11;
e6ed776f 424#endif
cfbe03c9
JS
425 a = ext->nlines;
426 for (y = 0, line = ext->lines; y < a; y++, line++) {
e6ed776f
GRG
427#ifndef VOID_SPRINTF
428 s +=
429#endif
cfbe03c9 430 sprintf(s, ",\n\"%s\"", *line);
e6ed776f 431#ifdef VOID_SPRINTF
cfbe03c9 432 s += strlen(*line) + 4;
e6ed776f 433#endif
cfbe03c9
JS
434 }
435 }
436 strcpy(s, ",\n\"XPMENDEXT\"");
437 *used_size += s - dataptr + 13;
438}
439
ea258ad3
DW
440#ifdef __OS2__
441/* Visual Age cannot deal with old, non-ansi, code */
442static int CommentsSize(XpmInfo* info)
443#else
444static int CommentsSize(info)
e6ed776f 445 XpmInfo *info;
ea258ad3 446#endif
cfbe03c9
JS
447{
448 int size = 0;
449
450 /* 5 = 2 (for "/_*") + 3 (for "*_/\n") */
451 if (info->hints_cmt)
452 size += 5 + strlen(info->hints_cmt);
453
454 if (info->colors_cmt)
455 size += 5 + strlen(info->colors_cmt);
456
457 if (info->pixels_cmt)
458 size += 5 + strlen(info->pixels_cmt);
459
460 return size;
461}