]> git.saurik.com Git - wxWidgets.git/blob - src/xpm/CrDatFrI.c
fix for a crash in ~wxFontList
[wxWidgets.git] / src / xpm / CrDatFrI.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 * CrDataFI.c: *
28 * *
29 * XPM library *
30 * Scan an image and possibly its mask and create an XPM array *
31 * *
32 * Developed by Arnaud Le Hors *
33 \*****************************************************************************/
34
35 #include "XpmI.h"
36
37 LFUNC(CreateColors, int, (char **dataptr, unsigned int *data_size,
38 XpmColor *colors, unsigned int ncolors,
39 unsigned int cpp));
40
41 LFUNC(CreatePixels, void, (char **dataptr, unsigned int width,
42 unsigned int height, unsigned int cpp,
43 unsigned int *pixels, XpmColor *colors));
44
45 LFUNC(CountExtensions, void, (XpmExtension *ext, unsigned int num,
46 unsigned int *ext_size,
47 unsigned int *ext_nlines));
48
49 LFUNC(CreateExtensions, void, (char **dataptr, unsigned int offset,
50 XpmExtension *ext, unsigned int num,
51 unsigned int ext_nlines));
52
53 #ifdef __OS2__
54 /* Visual Age cannot deal with old, non-ansi, code */
55 int
56 XpmCreateDataFromImage(
57 Display* display
58 , char*** data_return
59 , XImage* image
60 , XImage* shapeimage
61 , XpmAttributes* attributes
62 )
63 #else
64 int
65 XpmCreateDataFromImage(display, data_return, image, shapeimage, attributes)
66 Display *display;
67 char ***data_return;
68 XImage *image;
69 XImage *shapeimage;
70 XpmAttributes *attributes;
71 #endif
72 {
73 XpmImage xpmimage;
74 XpmInfo info;
75 int ErrorStatus;
76
77 /* initialize return value */
78 if (data_return)
79 *data_return = NULL;
80
81 /* create an XpmImage from the image */
82 ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage,
83 &xpmimage, attributes);
84 if (ErrorStatus != XpmSuccess)
85 return (ErrorStatus);
86
87 /* create the data from the XpmImage */
88 if (attributes) {
89 xpmSetInfo(&info, attributes);
90 ErrorStatus = XpmCreateDataFromXpmImage(data_return, &xpmimage, &info);
91 } else
92 ErrorStatus = XpmCreateDataFromXpmImage(data_return, &xpmimage, NULL);
93
94 /* free the XpmImage */
95 XpmFreeXpmImage(&xpmimage);
96
97 return (ErrorStatus);
98 }
99
100 #undef RETURN
101 #define RETURN(status) \
102 { \
103 ErrorStatus = status; \
104 goto exit; \
105 }
106
107 #ifdef __OS2__
108 /* Visual Age cannot deal with old, non-ansi, code */
109 int
110 XpmCreateDataFromXpmImage(char*** data_return, XpmImage* image, XpmInfo* info)
111 #else
112 int
113 XpmCreateDataFromXpmImage(data_return, image, info)
114 char ***data_return;
115 XpmImage *image;
116 XpmInfo *info;
117 #endif
118 {
119 /* calculation variables */
120 int ErrorStatus;
121 char buf[BUFSIZ];
122 char **header = NULL, **data, **sptr, **sptr2, *s;
123 unsigned int header_size, header_nlines;
124 unsigned int data_size, data_nlines;
125 unsigned int extensions = 0, ext_size = 0, ext_nlines = 0;
126 unsigned int offset, l, n;
127
128 *data_return = NULL;
129
130 extensions = info && (info->valuemask & XpmExtensions)
131 && info->nextensions;
132
133 /* compute the number of extensions lines and size */
134 if (extensions)
135 CountExtensions(info->extensions, info->nextensions,
136 &ext_size, &ext_nlines);
137
138 /*
139 * alloc a temporary array of char pointer for the header section which
140 * is the hints line + the color table lines
141 */
142 header_nlines = 1 + image->ncolors;
143 header_size = sizeof(char *) * header_nlines;
144 header = (char **) XpmCalloc(header_size, sizeof(char *));
145 if (!header)
146 return (XpmNoMemory);
147
148 /* print the hints line */
149 s = buf;
150 #ifndef VOID_SPRINTF
151 s +=
152 #endif
153 sprintf(s, "%d %d %d %d", image->width, image->height,
154 image->ncolors, image->cpp);
155 #ifdef VOID_SPRINTF
156 s += strlen(s);
157 #endif
158
159 if (info && (info->valuemask & XpmHotspot)) {
160 #ifndef VOID_SPRINTF
161 s +=
162 #endif
163 sprintf(s, " %d %d", info->x_hotspot, info->y_hotspot);
164 #ifdef VOID_SPRINTF
165 s += strlen(s);
166 #endif
167 }
168 if (extensions) {
169 strcpy(s, " XPMEXT");
170 s += 7;
171 }
172 l = s - buf + 1;
173 *header = (char *) XpmMalloc(l);
174 if (!*header)
175 RETURN(XpmNoMemory);
176 header_size += l;
177 strcpy(*header, buf);
178
179 /* print colors */
180 ErrorStatus = CreateColors(header + 1, &header_size,
181 image->colorTable, image->ncolors, image->cpp);
182
183 if (ErrorStatus != XpmSuccess)
184 RETURN(ErrorStatus);
185
186 /* now we know the size needed, alloc the data and copy the header lines */
187 offset = image->width * image->cpp + 1;
188 data_size = header_size + (image->height + ext_nlines) * sizeof(char *)
189 + image->height * offset + ext_size;
190
191 data = (char **) XpmMalloc(data_size);
192 if (!data)
193 RETURN(XpmNoMemory);
194
195 data_nlines = header_nlines + image->height + ext_nlines;
196 *data = (char *) (data + data_nlines);
197 n = image->ncolors;
198 for (l = 0, sptr = data, sptr2 = header; l <= n; l++, sptr++, sptr2++) {
199 strcpy(*sptr, *sptr2);
200 *(sptr + 1) = *sptr + strlen(*sptr2) + 1;
201 }
202
203 /* print pixels */
204 data[header_nlines] = (char *) data + header_size
205 + (image->height + ext_nlines) * sizeof(char *);
206
207 CreatePixels(data + header_nlines, image->width, image->height,
208 image->cpp, image->data, image->colorTable);
209
210 /* print extensions */
211 if (extensions)
212 CreateExtensions(data + header_nlines + image->height - 1, offset,
213 info->extensions, info->nextensions,
214 ext_nlines);
215
216 *data_return = data;
217 ErrorStatus = XpmSuccess;
218
219 /* exit point, free only locally allocated variables */
220 exit:
221 if (header) {
222 for (l = 0; l < header_nlines; l++)
223 if (header[l])
224 XpmFree(header[l]);
225 XpmFree(header);
226 }
227 return(ErrorStatus);
228 }
229
230 #ifdef __OS2__
231 /* Visual Age cannot deal with old, non-ansi, code */
232 static int
233 CreateColors(
234 char** dataptr
235 , unsigned int* data_size
236 , XpmColor* colors
237 , unsigned int ncolors
238 , unsigned int cpp
239 )
240 #else
241 static int
242 CreateColors(dataptr, data_size, colors, ncolors, cpp)
243 char **dataptr;
244 unsigned int *data_size;
245 XpmColor *colors;
246 unsigned int ncolors;
247 unsigned int cpp;
248 #endif
249 {
250 char buf[BUFSIZ];
251 unsigned int a, key, l;
252 char *s, *s2;
253 char **defaults;
254
255 for (a = 0; a < ncolors; a++, colors++, dataptr++) {
256
257 defaults = (char **) colors;
258 strncpy(buf, *defaults++, cpp);
259 s = buf + cpp;
260
261 for (key = 1; key <= NKEYS; key++, defaults++) {
262 if (s2 = *defaults) {
263 #ifndef VOID_SPRINTF
264 s +=
265 #endif
266 sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2);
267 #ifdef VOID_SPRINTF
268 s += strlen(s);
269 #endif
270 }
271 }
272 l = s - buf + 1;
273 s = (char *) XpmMalloc(l);
274 if (!s)
275 return (XpmNoMemory);
276 *data_size += l;
277 *dataptr = strcpy(s, buf);
278 }
279 return (XpmSuccess);
280 }
281
282 #ifdef __OS2__
283 /* Visual Age cannot deal with old, non-ansi, code */
284 static void CreatePixels(
285 char** dataptr
286 , unsigned int width
287 , unsigned int height
288 , unsigned int cpp
289 , unsigned int* pixels
290 , XpmColor* colors
291 )
292 #else
293 static void
294 CreatePixels(dataptr, width, height, cpp, pixels, colors)
295 char **dataptr;
296 unsigned int width;
297 unsigned int height;
298 unsigned int cpp;
299 unsigned int *pixels;
300 XpmColor *colors;
301 #endif
302 {
303 char *s;
304 unsigned int x, y, h, offset;
305
306 h = height - 1;
307 offset = width * cpp + 1;
308 for (y = 0; y < h; y++, dataptr++) {
309 s = *dataptr;
310 for (x = 0; x < width; x++, pixels++) {
311 strncpy(s, colors[*pixels].string, cpp);
312 s += cpp;
313 }
314 *s = '\0';
315 *(dataptr + 1) = *dataptr + offset;
316 }
317 /* duplicate some code to avoid a test in the loop */
318 s = *dataptr;
319 for (x = 0; x < width; x++, pixels++) {
320 strncpy(s, colors[*pixels].string, cpp);
321 s += cpp;
322 }
323 *s = '\0';
324 }
325
326 #ifdef __OS2__
327 /* Visual Age cannot deal with old, non-ansi, code */
328 static void CountExtensions(
329 XpmExtension* ext
330 , unsigned int num
331 , unsigned int* ext_size
332 , unsigned int* ext_nlines
333 )
334 #else
335 static void
336 CountExtensions(ext, num, ext_size, ext_nlines)
337 XpmExtension *ext;
338 unsigned int num;
339 unsigned int *ext_size;
340 unsigned int *ext_nlines;
341 #endif
342 {
343 unsigned int x, y, a, size, nlines;
344 char **line;
345
346 size = 0;
347 nlines = 0;
348 for (x = 0; x < num; x++, ext++) {
349 /* 1 for the name */
350 nlines += ext->nlines + 1;
351 /* 8 = 7 (for "XPMEXT ") + 1 (for 0) */
352 size += strlen(ext->name) + 8;
353 a = ext->nlines;
354 for (y = 0, line = ext->lines; y < a; y++, line++)
355 size += strlen(*line) + 1;
356 }
357 /* 10 and 1 are for the ending "XPMENDEXT" */
358 *ext_size = size + 10;
359 *ext_nlines = nlines + 1;
360 }
361
362 #ifdef __OS2__
363 /* Visual Age cannot deal with old, non-ansi, code */
364 static void
365 CreateExtensions(
366 char** dataptr
367 , unsigned int offset
368 , XpmExtension* ext
369 , unsigned int num
370 , unsigned int ext_nlines
371 )
372 #else
373 static void
374 CreateExtensions(dataptr, offset, ext, num, ext_nlines)
375 char **dataptr;
376 unsigned int offset;
377 XpmExtension *ext;
378 unsigned int num;
379 unsigned int ext_nlines;
380 #endif
381 {
382 unsigned int x, y, a, b;
383 char **line;
384
385 *(dataptr + 1) = *dataptr + offset;
386 dataptr++;
387 a = 0;
388 for (x = 0; x < num; x++, ext++) {
389 sprintf(*dataptr, "XPMEXT %s", ext->name);
390 a++;
391 if (a < ext_nlines)
392 *(dataptr + 1) = *dataptr + strlen(ext->name) + 8;
393 dataptr++;
394 b = ext->nlines;
395 for (y = 0, line = ext->lines; y < b; y++, line++) {
396 strcpy(*dataptr, *line);
397 a++;
398 if (a < ext_nlines)
399 *(dataptr + 1) = *dataptr + strlen(*line) + 1;
400 dataptr++;
401 }
402 }
403 strcpy(*dataptr, "XPMENDEXT");
404 }