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