]> git.saurik.com Git - wxWidgets.git/blob - src/xpm/CrBufFrI.c
support for multiple images in one file
[wxWidgets.git] / src / xpm / CrBufFrI.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 * CrBufFrI.c: *
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
35 #include "XpmI.h"
36
37 LFUNC(WriteColors, int, (char **dataptr, unsigned int *data_size,
38 unsigned int *used_size, XpmColor *colors,
39 unsigned int ncolors, unsigned int cpp));
40
41 LFUNC(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
46 LFUNC(WriteExtensions, void, (char *dataptr, unsigned int *used_size,
47 XpmExtension *ext, unsigned int num));
48
49 LFUNC(ExtensionsSize, int, (XpmExtension *ext, unsigned int num));
50 LFUNC(CommentsSize, int, (XpmInfo *info));
51
52 #ifdef __OS2__
53 /* Visual Age cannot deal with old, non-ansi, code */
54 int XpmCreateBufferFromImage(
55 Display* display
56 , char** buffer_return
57 , XImage* image
58 , XImage* shapeimage
59 , XpmAttributes* attributes
60 )
61 #else
62 int
63 XpmCreateBufferFromImage(display, buffer_return, image, shapeimage, attributes)
64 Display *display;
65 char **buffer_return;
66 XImage *image;
67 XImage *shapeimage;
68 XpmAttributes *attributes;
69 #endif
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 { \
104 ErrorStatus = status; \
105 goto error; \
106 }
107
108 #ifdef __OS2__
109 /* Visual Age cannot deal with old, non-ansi, code */
110 int XpmCreateBufferFromXpmImage(char** buffer_return, XpmImage* image, XpmInfo* info)
111 #else
112 int
113 XpmCreateBufferFromXpmImage(buffer_return, image, info)
114 char **buffer_return;
115 XpmImage *image;
116 XpmInfo *info;
117 #endif
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 */
140 #ifndef VOID_SPRINTF
141 used_size =
142 #endif
143 sprintf(buf, "/* XPM */\nstatic char * image_name[] = {\n");
144 #ifdef VOID_SPRINTF
145 used_size = strlen(buf);
146 #endif
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) {
155 #ifndef VOID_SPRINTF
156 used_size +=
157 #endif
158 sprintf(ptr + used_size, "/*%s*/\n", info->hints_cmt);
159 #ifdef VOID_SPRINTF
160 used_size += strlen(info->hints_cmt) + 5;
161 #endif
162 }
163 #ifndef VOID_SPRINTF
164 l =
165 #endif
166 sprintf(buf, "\"%d %d %d %d", image->width, image->height,
167 image->ncolors, image->cpp);
168 #ifdef VOID_SPRINTF
169 l = strlen(buf);
170 #endif
171
172 if (info && (info->valuemask & XpmHotspot)) {
173 #ifndef VOID_SPRINTF
174 l +=
175 #endif
176 sprintf(buf + l, " %d %d", info->x_hotspot, info->y_hotspot);
177 #ifdef VOID_SPRINTF
178 l = strlen(buf);
179 #endif
180 }
181 if (extensions) {
182 #ifndef VOID_SPRINTF
183 l +=
184 #endif
185 sprintf(buf + l, " XPMEXT");
186 #ifdef VOID_SPRINTF
187 l = strlen(buf);
188 #endif
189 }
190 #ifndef VOID_SPRINTF
191 l +=
192 #endif
193 sprintf(buf + l, "\",\n");
194 #ifdef VOID_SPRINTF
195 l = strlen(buf);
196 #endif
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) {
207 #ifndef VOID_SPRINTF
208 used_size +=
209 #endif
210 sprintf(ptr + used_size, "/*%s*/\n", info->colors_cmt);
211 #ifdef VOID_SPRINTF
212 used_size += strlen(info->colors_cmt) + 5;
213 #endif
214 }
215 ErrorStatus = WriteColors(&ptr, &ptr_size, &used_size,
216 image->colorTable, image->ncolors, image->cpp);
217
218 if (ErrorStatus != XpmSuccess)
219 RETURN(ErrorStatus);
220
221 /*
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')
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) {
235 #ifndef VOID_SPRINTF
236 used_size +=
237 #endif
238 sprintf(ptr + used_size, "/*%s*/\n", info->pixels_cmt);
239 #ifdef VOID_SPRINTF
240 used_size += strlen(info->pixels_cmt) + 5;
241 #endif
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 */
252 strcpy(ptr + used_size, "};\n");
253
254 *buffer_return = ptr;
255
256 return (XpmSuccess);
257
258 /* exit point in case of error, free only locally allocated variables */
259 error:
260 if (ptr)
261 XpmFree(ptr);
262 return (ErrorStatus);
263 }
264
265 #ifdef __OS2__
266 /* Visual Age cannot deal with old, non-ansi, code */
267 static 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
276 static int
277 WriteColors(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;
284 #endif
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) {
301 #ifndef VOID_SPRINTF
302 s +=
303 #endif
304 sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2);
305 #ifdef VOID_SPRINTF
306 s += strlen(s);
307 #endif
308 }
309 }
310 strcpy(s, "\",\n");
311 l = s + 3 - buf;
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
323 #ifdef __OS2__
324 /* Visual Age cannot deal with old, non-ansi, code */
325 static 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
335 static void
336 WritePixels(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;
344 #endif
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
369 #ifdef __OS2__
370 /* Visual Age cannot deal with old, non-ansi, code */
371 static int
372 ExtensionsSize(XpmExtension* ext, unsigned int num)
373 #else
374 static int
375 ExtensionsSize(ext, num)
376 XpmExtension *ext;
377 unsigned int num;
378 #endif
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
396 #ifdef __OS2__
397 /* Visual Age cannot deal with old, non-ansi, code */
398 static void WriteExtensions(
399 char* dataptr
400 , unsigned int* used_size
401 , XpmExtension* ext
402 , unsigned int num
403 )
404 #else
405 static void
406 WriteExtensions(dataptr, used_size, ext, num)
407 char *dataptr;
408 unsigned int *used_size;
409 XpmExtension *ext;
410 unsigned int num;
411 #endif
412 {
413 unsigned int x, y, a;
414 char **line;
415 char *s = dataptr;
416
417 for (x = 0; x < num; x++, ext++) {
418 #ifndef VOID_SPRINTF
419 s +=
420 #endif
421 sprintf(s, ",\n\"XPMEXT %s\"", ext->name);
422 #ifdef VOID_SPRINTF
423 s += strlen(ext->name) + 11;
424 #endif
425 a = ext->nlines;
426 for (y = 0, line = ext->lines; y < a; y++, line++) {
427 #ifndef VOID_SPRINTF
428 s +=
429 #endif
430 sprintf(s, ",\n\"%s\"", *line);
431 #ifdef VOID_SPRINTF
432 s += strlen(*line) + 4;
433 #endif
434 }
435 }
436 strcpy(s, ",\n\"XPMENDEXT\"");
437 *used_size += s - dataptr + 13;
438 }
439
440 #ifdef __OS2__
441 /* Visual Age cannot deal with old, non-ansi, code */
442 static int CommentsSize(XpmInfo* info)
443 #else
444 static int CommentsSize(info)
445 XpmInfo *info;
446 #endif
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 }