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