]> git.saurik.com Git - wxWidgets.git/blob - src/mac/xpm/CrBufFrI.c
Added comments explaining my recent changes
[wxWidgets.git] / src / mac / 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)!=NULL)
273 {
274 #ifndef VOID_SPRINTF
275 s +=
276 #endif
277 sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2);
278 #ifdef VOID_SPRINTF
279 s += strlen(s);
280 #endif
281 }
282 }
283 strcpy(s, "\",\n");
284 l = s + 3 - buf;
285 s = (char *) XpmRealloc(*dataptr, *data_size + l);
286 if (!s)
287 return (XpmNoMemory);
288 *data_size += l;
289 strcpy(s + *used_size, buf);
290 *used_size += l;
291 *dataptr = s;
292 }
293 return (XpmSuccess);
294 }
295
296 static void
297 WritePixels(dataptr, used_size, width, height, cpp, pixels, colors)
298 char *dataptr;
299 unsigned int *used_size;
300 unsigned int width;
301 unsigned int height;
302 unsigned int cpp;
303 unsigned int *pixels;
304 XpmColor *colors;
305 {
306 char *s = dataptr;
307 unsigned int x, y, h;
308
309 h = height - 1;
310 for (y = 0; y < h; y++) {
311 *s++ = '"';
312 for (x = 0; x < width; x++, pixels++) {
313 strncpy(s, colors[*pixels].string, cpp);
314 s += cpp;
315 }
316 strcpy(s, "\",\n");
317 s += 3;
318 }
319 /* duplicate some code to avoid a test in the loop */
320 *s++ = '"';
321 for (x = 0; x < width; x++, pixels++) {
322 strncpy(s, colors[*pixels].string, cpp);
323 s += cpp;
324 }
325 *s++ = '"';
326 *used_size += s - dataptr;
327 }
328
329 static int
330 ExtensionsSize(ext, num)
331 XpmExtension *ext;
332 unsigned int num;
333 {
334 unsigned int x, y, a, size;
335 char **line;
336
337 size = 0;
338 for (x = 0; x < num; x++, ext++) {
339 /* 11 = 10 (for ',\n"XPMEXT ') + 1 (for '"') */
340 size += strlen(ext->name) + 11;
341 a = ext->nlines;
342 for (y = 0, line = ext->lines; y < a; y++, line++)
343 /* 4 = 3 (for ',\n"') + 1 (for '"') */
344 size += strlen(*line) + 4;
345 }
346 /* 13 is for ',\n"XPMENDEXT"' */
347 return size + 13;
348 }
349
350 static void
351 WriteExtensions(dataptr, used_size, ext, num)
352 char *dataptr;
353 unsigned int *used_size;
354 XpmExtension *ext;
355 unsigned int num;
356 {
357 unsigned int x, y, a;
358 char **line;
359 char *s = dataptr;
360
361 for (x = 0; x < num; x++, ext++) {
362 #ifndef VOID_SPRINTF
363 s +=
364 #endif
365 sprintf(s, ",\n\"XPMEXT %s\"", ext->name);
366 #ifdef VOID_SPRINTF
367 s += strlen(ext->name) + 11;
368 #endif
369 a = ext->nlines;
370 for (y = 0, line = ext->lines; y < a; y++, line++) {
371 #ifndef VOID_SPRINTF
372 s +=
373 #endif
374 sprintf(s, ",\n\"%s\"", *line);
375 #ifdef VOID_SPRINTF
376 s += strlen(*line) + 4;
377 #endif
378 }
379 }
380 strcpy(s, ",\n\"XPMENDEXT\"");
381 *used_size += s - dataptr + 13;
382 }
383
384 static int
385 CommentsSize(info)
386 XpmInfo *info;
387 {
388 int size = 0;
389
390 /* 5 = 2 (for "/_*") + 3 (for "*_/\n") */
391 if (info->hints_cmt)
392 size += 5 + strlen(info->hints_cmt);
393
394 if (info->colors_cmt)
395 size += 5 + strlen(info->colors_cmt);
396
397 if (info->pixels_cmt)
398 size += 5 + strlen(info->pixels_cmt);
399
400 return size;
401 }