]>
Commit | Line | Data |
---|---|---|
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 | } |