]> git.saurik.com Git - wxWidgets.git/blame - src/xpm/CrDatFrI.c
XPM updates
[wxWidgets.git] / src / xpm / CrDatFrI.c
CommitLineData
cfbe03c9 1/*
e6ed776f 2 * Copyright (C) 1989-95 GROUPE BULL
cfbe03c9
JS
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/*****************************************************************************\
e6ed776f 27* CrDataFI.c: *
cfbe03c9
JS
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
e6ed776f 35#include "XpmI.h"
cfbe03c9
JS
36
37LFUNC(CreateColors, int, (char **dataptr, unsigned int *data_size,
38 XpmColor *colors, unsigned int ncolors,
39 unsigned int cpp));
40
41LFUNC(CreatePixels, void, (char **dataptr, unsigned int width,
42 unsigned int height, unsigned int cpp,
43 unsigned int *pixels, XpmColor *colors));
44
45LFUNC(CountExtensions, void, (XpmExtension *ext, unsigned int num,
46 unsigned int *ext_size,
47 unsigned int *ext_nlines));
48
49LFUNC(CreateExtensions, void, (char **dataptr, unsigned int offset,
50 XpmExtension *ext, unsigned int num,
51 unsigned int ext_nlines));
52
ea258ad3
DW
53#ifdef __OS2__
54/* Visual Age cannot deal with old, non-ansi, code */
55int
56XpmCreateDataFromImage(
57 Display* display
58, char*** data_return
59, XImage* image
60, XImage* shapeimage
61, XpmAttributes* attributes
62)
63#else
cfbe03c9 64int
e6ed776f
GRG
65XpmCreateDataFromImage(display, data_return, image, shapeimage, attributes)
66 Display *display;
67 char ***data_return;
68 XImage *image;
69 XImage *shapeimage;
70 XpmAttributes *attributes;
ea258ad3 71#endif
cfbe03c9
JS
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{ \
e6ed776f
GRG
103 ErrorStatus = status; \
104 goto exit; \
cfbe03c9
JS
105}
106
ea258ad3
DW
107#ifdef __OS2__
108/* Visual Age cannot deal with old, non-ansi, code */
109int
110XpmCreateDataFromXpmImage(char*** data_return, XpmImage* image, XpmInfo* info)
111#else
cfbe03c9 112int
e6ed776f
GRG
113XpmCreateDataFromXpmImage(data_return, image, info)
114 char ***data_return;
115 XpmImage *image;
116 XpmInfo *info;
ea258ad3 117#endif
cfbe03c9
JS
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;
e6ed776f
GRG
150#ifndef VOID_SPRINTF
151 s +=
152#endif
cfbe03c9
JS
153 sprintf(s, "%d %d %d %d", image->width, image->height,
154 image->ncolors, image->cpp);
e6ed776f 155#ifdef VOID_SPRINTF
cfbe03c9 156 s += strlen(s);
e6ed776f 157#endif
cfbe03c9
JS
158
159 if (info && (info->valuemask & XpmHotspot)) {
e6ed776f
GRG
160#ifndef VOID_SPRINTF
161 s +=
162#endif
cfbe03c9 163 sprintf(s, " %d %d", info->x_hotspot, info->y_hotspot);
e6ed776f 164#ifdef VOID_SPRINTF
cfbe03c9 165 s += strlen(s);
e6ed776f 166#endif
cfbe03c9 167 }
e6ed776f
GRG
168 if (extensions) {
169 strcpy(s, " XPMEXT");
170 s += 7;
171 }
172 l = s - buf + 1;
cfbe03c9
JS
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;
e6ed776f
GRG
217 ErrorStatus = XpmSuccess;
218
219/* exit point, free only locally allocated variables */
220exit:
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);
cfbe03c9
JS
228}
229
ea258ad3
DW
230#ifdef __OS2__
231/* Visual Age cannot deal with old, non-ansi, code */
232static int
233CreateColors(
234 char** dataptr
235, unsigned int* data_size
236, XpmColor* colors
237, unsigned int ncolors
238, unsigned int cpp
239)
240#else
cfbe03c9 241static int
e6ed776f
GRG
242CreateColors(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;
ea258ad3 248#endif
cfbe03c9
JS
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) {
e6ed776f
GRG
263#ifndef VOID_SPRINTF
264 s +=
265#endif
cfbe03c9 266 sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2);
e6ed776f 267#ifdef VOID_SPRINTF
cfbe03c9 268 s += strlen(s);
e6ed776f 269#endif
cfbe03c9
JS
270 }
271 }
e6ed776f 272 l = s - buf + 1;
cfbe03c9
JS
273 s = (char *) XpmMalloc(l);
274 if (!s)
275 return (XpmNoMemory);
276 *data_size += l;
e6ed776f 277 *dataptr = strcpy(s, buf);
cfbe03c9
JS
278 }
279 return (XpmSuccess);
280}
281
ea258ad3
DW
282#ifdef __OS2__
283/* Visual Age cannot deal with old, non-ansi, code */
284static 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
cfbe03c9 293static void
e6ed776f
GRG
294CreatePixels(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;
ea258ad3 301#endif
cfbe03c9
JS
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
ea258ad3
DW
326#ifdef __OS2__
327/* Visual Age cannot deal with old, non-ansi, code */
328static void CountExtensions(
329 XpmExtension* ext
330, unsigned int num
331, unsigned int* ext_size
332, unsigned int* ext_nlines
333)
334#else
cfbe03c9 335static void
e6ed776f
GRG
336CountExtensions(ext, num, ext_size, ext_nlines)
337 XpmExtension *ext;
338 unsigned int num;
339 unsigned int *ext_size;
340 unsigned int *ext_nlines;
ea258ad3 341#endif
cfbe03c9
JS
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
ea258ad3
DW
362#ifdef __OS2__
363/* Visual Age cannot deal with old, non-ansi, code */
364static void
365CreateExtensions(
366 char** dataptr
367, unsigned int offset
368, XpmExtension* ext
369, unsigned int num
370, unsigned int ext_nlines
371)
372#else
cfbe03c9 373static void
e6ed776f
GRG
374CreateExtensions(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;
ea258ad3 380#endif
cfbe03c9
JS
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}