]> git.saurik.com Git - wxWidgets.git/blob - src/xpm/crdatfri.c
wxWindow::Fit() infinite loop bug fixed
[wxWidgets.git] / src / xpm / crdatfri.c
1 /*
2 * Copyright (C) 1989-94 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 * XpmCrDataFI.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 "xpm34p.h"
36 #ifdef VMS
37 #include "sys$library:string.h"
38 #else
39 #if defined(SYSV) || defined(SVR4)
40 #include <string.h>
41 #else
42 #include <strings.h>
43 #endif
44 #endif
45
46 LFUNC(CreateColors, int, (char **dataptr, unsigned int *data_size,
47 XpmColor *colors, unsigned int ncolors,
48 unsigned int cpp));
49
50 LFUNC(CreatePixels, void, (char **dataptr, unsigned int width,
51 unsigned int height, unsigned int cpp,
52 unsigned int *pixels, XpmColor *colors));
53
54 LFUNC(CountExtensions, void, (XpmExtension *ext, unsigned int num,
55 unsigned int *ext_size,
56 unsigned int *ext_nlines));
57
58 LFUNC(CreateExtensions, void, (char **dataptr, unsigned int offset,
59 XpmExtension *ext, unsigned int num,
60 unsigned int ext_nlines));
61
62 int
63 XpmCreateDataFromImage(Display *display, char ***data_return, XImage *image,
64 XImage *shapeimage, XpmAttributes *attributes)
65 {
66 XpmImage xpmimage;
67 XpmInfo info;
68 int ErrorStatus;
69
70 /* initialize return value */
71 if (data_return)
72 *data_return = NULL;
73
74 /* create an XpmImage from the image */
75 ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage,
76 &xpmimage, attributes);
77 if (ErrorStatus != XpmSuccess)
78 return (ErrorStatus);
79
80 /* create the data from the XpmImage */
81 if (attributes) {
82 xpmSetInfo(&info, attributes);
83 ErrorStatus = XpmCreateDataFromXpmImage(data_return, &xpmimage, &info);
84 } else
85 ErrorStatus = XpmCreateDataFromXpmImage(data_return, &xpmimage, NULL);
86
87 /* free the XpmImage */
88 XpmFreeXpmImage(&xpmimage);
89
90 return (ErrorStatus);
91 }
92
93 #undef RETURN
94 #define RETURN(status) \
95 { \
96 if (header) { \
97 for (l = 0; l < header_nlines; l++) \
98 if (header[l]) \
99 XpmFree(header[l]); \
100 XpmFree(header); \
101 } \
102 return(status); \
103 }
104
105 int
106 XpmCreateDataFromXpmImage(char ***data_return, XpmImage *image, XpmInfo *info)
107 {
108 /* calculation variables */
109 int ErrorStatus;
110 char buf[BUFSIZ];
111 char **header = NULL, **data, **sptr, **sptr2, *s;
112 unsigned int header_size, header_nlines;
113 unsigned int data_size, data_nlines;
114 unsigned int extensions = 0, ext_size = 0, ext_nlines = 0;
115 unsigned int offset, l, n;
116
117 *data_return = NULL;
118
119 extensions = info && (info->valuemask & XpmExtensions)
120 && info->nextensions;
121
122 /* compute the number of extensions lines and size */
123 if (extensions)
124 CountExtensions(info->extensions, info->nextensions,
125 &ext_size, &ext_nlines);
126
127 /*
128 * alloc a temporary array of char pointer for the header section which
129 * is the hints line + the color table lines
130 */
131 header_nlines = 1 + image->ncolors;
132 header_size = sizeof(char *) * header_nlines;
133 header = (char **) XpmCalloc(header_size, sizeof(char *));
134 if (!header)
135 return (XpmNoMemory);
136
137 /* print the hints line */
138 s = buf;
139 sprintf(s, "%d %d %d %d", image->width, image->height,
140 image->ncolors, image->cpp);
141 s += strlen(s);
142
143 if (info && (info->valuemask & XpmHotspot)) {
144 sprintf(s, " %d %d", info->x_hotspot, info->y_hotspot);
145 s += strlen(s);
146 }
147 if (extensions)
148 sprintf(s, " XPMEXT");
149
150 l = strlen(buf) + 1;
151 *header = (char *) XpmMalloc(l);
152 if (!*header)
153 RETURN(XpmNoMemory);
154 header_size += l;
155 strcpy(*header, buf);
156
157 /* print colors */
158 ErrorStatus = CreateColors(header + 1, &header_size,
159 image->colorTable, image->ncolors, image->cpp);
160
161 if (ErrorStatus != XpmSuccess)
162 RETURN(ErrorStatus);
163
164 /* now we know the size needed, alloc the data and copy the header lines */
165 offset = image->width * image->cpp + 1;
166 data_size = header_size + (image->height + ext_nlines) * sizeof(char *)
167 + image->height * offset + ext_size;
168
169 data = (char **) XpmMalloc(data_size);
170 if (!data)
171 RETURN(XpmNoMemory);
172
173 data_nlines = header_nlines + image->height + ext_nlines;
174 *data = (char *) (data + data_nlines);
175 n = image->ncolors;
176 for (l = 0, sptr = data, sptr2 = header; l <= n; l++, sptr++, sptr2++) {
177 strcpy(*sptr, *sptr2);
178 *(sptr + 1) = *sptr + strlen(*sptr2) + 1;
179 }
180
181 /* print pixels */
182 data[header_nlines] = (char *) data + header_size
183 + (image->height + ext_nlines) * sizeof(char *);
184
185 CreatePixels(data + header_nlines, image->width, image->height,
186 image->cpp, image->data, image->colorTable);
187
188 /* print extensions */
189 if (extensions)
190 CreateExtensions(data + header_nlines + image->height - 1, offset,
191 info->extensions, info->nextensions,
192 ext_nlines);
193
194 *data_return = data;
195
196 RETURN(XpmSuccess);
197 }
198
199 static int
200 CreateColors(char **dataptr, unsigned int *data_size, XpmColor *colors, unsigned int ncolors, unsigned int cpp)
201 {
202 char buf[BUFSIZ];
203 unsigned int a, key, l;
204 char *s, *s2;
205 char **defaults;
206
207 for (a = 0; a < ncolors; a++, colors++, dataptr++) {
208
209 defaults = (char **) colors;
210 strncpy(buf, *defaults++, cpp);
211 s = buf + cpp;
212
213 for (key = 1; key <= NKEYS; key++, defaults++) {
214 if (s2 = *defaults) {
215 sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2);
216 s += strlen(s);
217 }
218 }
219 l = strlen(buf) + 1;
220 s = (char *) XpmMalloc(l);
221 if (!s)
222 return (XpmNoMemory);
223 *data_size += l;
224 strcpy(s, buf);
225 *dataptr = s;
226 }
227 return (XpmSuccess);
228 }
229
230 static void
231 CreatePixels(char **dataptr, unsigned int width, unsigned int height, unsigned int cpp,
232 unsigned int *pixels, XpmColor *colors)
233 {
234 char *s;
235 unsigned int x, y, h, offset;
236
237 h = height - 1;
238 offset = width * cpp + 1;
239 for (y = 0; y < h; y++, dataptr++) {
240 s = *dataptr;
241 for (x = 0; x < width; x++, pixels++) {
242 strncpy(s, colors[*pixels].string, cpp);
243 s += cpp;
244 }
245 *s = '\0';
246 *(dataptr + 1) = *dataptr + offset;
247 }
248 /* duplicate some code to avoid a test in the loop */
249 s = *dataptr;
250 for (x = 0; x < width; x++, pixels++) {
251 strncpy(s, colors[*pixels].string, cpp);
252 s += cpp;
253 }
254 *s = '\0';
255 }
256
257 static void
258 CountExtensions(XpmExtension *ext, unsigned int num, unsigned int *ext_size, unsigned int *ext_nlines)
259 {
260 unsigned int x, y, a, size, nlines;
261 char **line;
262
263 size = 0;
264 nlines = 0;
265 for (x = 0; x < num; x++, ext++) {
266 /* 1 for the name */
267 nlines += ext->nlines + 1;
268 /* 8 = 7 (for "XPMEXT ") + 1 (for 0) */
269 size += strlen(ext->name) + 8;
270 a = ext->nlines;
271 for (y = 0, line = ext->lines; y < a; y++, line++)
272 size += strlen(*line) + 1;
273 }
274 /* 10 and 1 are for the ending "XPMENDEXT" */
275 *ext_size = size + 10;
276 *ext_nlines = nlines + 1;
277 }
278
279 static void
280 CreateExtensions(char **dataptr, unsigned int offset, XpmExtension *ext, unsigned int num, unsigned int ext_nlines)
281 {
282 unsigned int x, y, a, b;
283 char **line;
284
285 *(dataptr + 1) = *dataptr + offset;
286 dataptr++;
287 a = 0;
288 for (x = 0; x < num; x++, ext++) {
289 sprintf(*dataptr, "XPMEXT %s", ext->name);
290 a++;
291 if (a < ext_nlines)
292 *(dataptr + 1) = *dataptr + strlen(ext->name) + 8;
293 dataptr++;
294 b = ext->nlines;
295 for (y = 0, line = ext->lines; y < b; y++, line++) {
296 strcpy(*dataptr, *line);
297 a++;
298 if (a < ext_nlines)
299 *(dataptr + 1) = *dataptr + strlen(*line) + 1;
300 dataptr++;
301 }
302 }
303 strcpy(*dataptr, "XPMENDEXT");
304 }